Day16

Day16

一、迭代器

深入迭代器-foreach的底层

for (String element : list) {System.out.println(element);}

底层:

//使用foreach循环遍历集合的底层实现:String element;for(Iterator it = list.iterator();it.hasNext();System.out.println(element))element = (String) it.next();

注意:Iterator it = list.iterator();中Iterator是一个接口,集合类都必须实现Iterable接口,而在Iterable接口中定义了一个方法,该方法要求返回一个Iterator接口实现类的对象。所以ArrayList类中必定有一个iterator()方法,该方法实际上是重写的Iterable接口的方法,返回的是iterator实现类对象。

//ArrayList中重写的Iterable接口的方法,返回iterator实现类对象
@Override
public Iterator<E> iterator() {return new Itr();
}

因此也必定有一个类去实现iterator接口:

 private class Itr implements Iterator<E> {int cursor;       // index of next element to returnint lastRet = -1; // index of last element returned; -1 if no such// To track modifications to the list during iterationint expectedModCount = modCount;// Checks if the list has more elements@Overridepublic boolean hasNext() {return cursor != size();}// Returns the next element in the iteration@SuppressWarnings("unchecked")@Overridepublic E next() {checkForComodification();int i = cursor;if (i >= size())throw new NoSuchElementException();Object[] elementData = ArrayList.this.elementData;if (i >= elementData.length)throw new ConcurrentModificationException();cursor = i + 1;return (E) elementData[lastRet = i];}// Removes the last element returned by this iterator@Overridepublic void remove() {if (lastRet < 0)throw new IllegalStateException();checkForComodification();try {ArrayList.this.remove(lastRet);cursor = lastRet;lastRet = -1;expectedModCount = modCount;} catch (IndexOutOfBoundsException ex) {throw new ConcurrentModificationException();}}// Checks if the list has been modified during iterationfinal void checkForComodification() {if (modCount != expectedModCount)throw new ConcurrentModificationException();}}// Other methods and fields of ArrayList...
}

深入迭代器 – Iterator

场景:

public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("aaa");list.add("bbb");list.add("ccc");list.add("ddd");list.add("eee");list.remove("bbb");Iterator<String> it = list.iterator();while(it.hasNext()){String element = it.next();System.out.println(element);}}

底层

Iterator接口:

public interface Iterator<E> {//判断是否有可迭代的元素boolean hasNext();//返回下一个元素E next();//删除(默认方法) -- 报错default void remove() {throw new UnsupportedOperationException("remove");}
}

抽象类,用于记录外部操作数(添加和删除,改和查不影响数据数量)

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {//外部操作数(记录集合添加、删除的次数)protected transient int modCount = 0;//6
}

ArrayList类(一部分):

public class ArrayList<E> extends AbstractList<E> implements List<E>{//数据容器 - ["aaa","ccc","ddd","eee",null,null,null,null,null,null]transient Object[] elementData;//数据个数(指针)private int size;//4//e - "eee"public boolean add(E e) {ensureCapacityInternal(size + 1);  // 判断是否扩容elementData[size++] = e;return true;}private void ensureCapacityInternal(int minCapacity) {if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);}ensureExplicitCapacity(minCapacity);}private void ensureExplicitCapacity(int minCapacity) {modCount++;if (minCapacity - elementData.length > 0)grow(minCapacity);}//o - "bbb"public boolean remove(Object o) {if (o == null) {for (int index = 0; index < size; index++)if (elementData[index] == null) {fastRemove(index);return true;}} else {//线性查询(从头遍历到size的位置)for (int index = 0; index < size; index++)if (o.equals(elementData[index])) {//删除元素(传入下标)fastRemove(index);return true;}}return false;}//index - 1private void fastRemove(int index) {modCount++;int numMoved = size - index - 1;//计算移动次数if (numMoved > 0)System.arraycopy(elementData, index+1, elementData, index, numMoved);elementData[--size] = null; // clear to let GC do its work}public Iterator<E> iterator() {return new Itr();}//Itr是成员内部类,因为Itr中使用到了外部类(ArrayList)的成员属性(modCount、size)private class Itr implements Iterator<E> {int cursor;       // 游标 - 4int lastRet = -1; // 当前元素的下标 - 3int expectedModCount = modCount;//内部操作数 - 6public boolean hasNext() {return cursor != size;//4 != 4}@SuppressWarnings("unchecked")public E next() {checkForComodification();//判断外部操作数和内部操作数是否相同int i = cursor;//i = 3if (i >= size)throw new NoSuchElementException();//elementData - ["aaa","ccc","ddd","eee",null,null,null,null,null,null]Object[] elementData = ArrayList.this.elementData;if (i >= elementData.length)throw new ConcurrentModificationException();cursor = i + 1;//cursor - 4return (E) elementData[lastRet = i];}final void checkForComodification() {if (modCount != expectedModCount)throw new ConcurrentModificationException();}public void remove() {if (lastRet < 0)throw new IllegalStateException();checkForComodification();//判断外部操作数和内部操作数是否相同try {//Itr依赖于ArrayList对象的remove()去删除元素ArrayList.this.remove(lastRet);cursor = lastRet;lastRet = -1;//重新将外部操作数赋值给内部操作数,保证内外部操作数一致不会出现脏数据expectedModCount = modCount;} catch (IndexOutOfBoundsException ex) {throw new ConcurrentModificationException();}}@Override@SuppressWarnings("unchecked")public void forEachRemaining(Consumer<? super E> consumer) {Objects.requireNonNull(consumer);final int size = ArrayList.this.size;int i = cursor;if (i >= size) {return;}final Object[] elementData = ArrayList.this.elementData;if (i >= elementData.length) {throw new ConcurrentModificationException();}while (i != size && modCount == expectedModCount) {consumer.accept((E) elementData[i++]);}// update once at end of iteration to reduce heap write trafficcursor = i;lastRet = i - 1;checkForComodification();}}
}

理解:
1.transient Object[] elementData是一个数组容器,最开始默认长度为10,size为指针,代表数据的个数。

2.ensureCapacityInternal()方法和 ensureExplicitCapacity()方法的作用为判断是否需要扩容,如果需要则调用扩容相关方法进行扩容。除此之外,还会 将外部操作数modCount++,因此在ArrayList底层中添加数据的流程就是先判断并扩容,然后添加数据到一维对象数组中并调整指针,指向下一个位置。

3.fastRemove()方法首先将外部操作数modCount++,然后计算多少个元素需要移动,由于删除的逻辑为删除当前位置的元素,并把后面的元素提前,所以计算方法为size - index - 1,如果该结果大于0(说明有要删除的元素),则用System.arraycopy和删除最后一个元素的组合技进行删除。因此删除数据的流程逻辑就是遍历元素然后调用fastRemove()方法进行删除。

4.ArrayList中用来实现Iterator的内部类为Itr,它定义了游标,当前元素的下标以及内部操作数三个属性。游标和size指针类似,用来指向下一个位置。当前元素下标初始值赋为-1。内部操作数值赋为modCount,即和外部操作数相等。hasNext()方法逻辑为当前游标和size指针是否相同,如果不同则说明游标还没到达最大数量,即存在元素。next()方法逻辑为先检查内部操作数和外部操作数是否相同,如果相同则再用游标返回对应的数组中的值。

Iterator<String> it = list.iterator();while(it.hasNext()){			String element = it.next();if(element.equals("bbb")){//list.remove(element);//modCount - 6it.remove();}}

5.如果在迭代器遍历中要删除元素的话,不能用list.remove()方法,只能用it.remove()。即不能直接用ArrayList类中定义的remove方法,因为调用它会使得外部操作数加一,在迭代器遍历时next()方法就会报错,所以应该用Itr类中定义的remove()方法,重新将外部操作数赋值给内部操作数,保证内外部操作数一致不会出现脏数据。

深入迭代器 – ListIterator

逻辑和Iterator相同,但在Itr类中新增了一个内部类ListItr,里面有新增的方法,如add,set,指定下标,hasprevious(),previous(),倒序遍历等。

public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("aaa");list.add("bbb");list.add("ccc");list.add("ddd");list.add("eee");ListIterator<String> listIterator = list.listIterator();while(listIterator.hasNext()){String element = listIterator.next();if(element.equals("bbb")){listIterator.set("xyz");   // 替换当前元素为 "xyz"listIterator.add("xyz");   // 在当前元素后添加新的 "xyz"listIterator.previous();   // 回到刚添加的 "xyz" 位置listIterator.remove();     // 删除替换后的 "xyz" 元素}}/**ListIterator<String> listIterator = list.listIterator(1);while(listIterator.hasNext()){String element = listIterator.next();System.out.println(element);}*//**ListIterator<String> listIterator = list.listIterator(list.size());while(listIterator.hasPrevious()){String element = listIterator.previous();System.out.println(element);}*/for (String element : list) {System.out.println(element);}}

二、泛型在集合中的使用

使用泛型的好处

  1. 类型安全:在编译时检查类型错误,防止将错误类型的对象添加到列表中。
  2. 可读性和可维护性:代码更容易理解和维护,因为类型信息显式显示在代码中。
  3. 避免类型转换:无需显式类型转换,因为泛型提供了编译时类型检查。
/*** @param <E> 创建对象时规定类型* * E - element - 元素* T - Type - 类型* * 注意:设置泛型可以有多个* <K,V> -> * 			K - Key 键* 			V - Value 值* * <N,V> -> * 			N - name 名* 			V - Value 值*/
public class MyArrayList<E> {public void add(E e){}
}
public static void main(String[] args) {ArrayList<Integer> list = new ArrayList<>();list.add(100);list.add(100);list.add(100);System.out.println("-----------------------------");MyArrayList<Integer> myArrayList = new MyArrayList<>();myArrayList.add(100);myArrayList.add(100);myArrayList.add(100);}

泛型限定

假设继承关系为继承关系:Object.A.B

public static void main(String[] args) {}//?表示任意类型public static ArrayList<?> method01(){//		ArrayList<Object> list = new ArrayList<>();
//		ArrayList<A> list = new ArrayList<>();ArrayList<B> list = new ArrayList<>();return list; }//? extends A 表示A类型或者是A的子类类型public static ArrayList<? extends A> method02(){//		ArrayList<A> list = new ArrayList<>();ArrayList<B> list = new ArrayList<>();return list; }//? super A 表示A类型或者是A的父类类型public static ArrayList<? super A> method03(){//		ArrayList<A> list = new ArrayList<>();ArrayList<Object> list = new ArrayList<>();return list; }

泛型的使用

需求:设计一个管理系统的接口
分析:
学生管理系统(数据的增删改查) – 学生对象
用户管理系统(数据的增删改查) – 用户对象
图书管理系统(数据的增删改查) – 图书对象

//管理系统的结构
public interface ManagerSystem<T> {public int add(T t);public int remove(T t);
}
public class Student {}//学生管理系统的实现类
public class StudentManagerSystem implements ManagerSystem<Student>{@Overridepublic int add(Student t) {// TODO Auto-generated method stubreturn 0;}@Overridepublic int remove(Student t) {// TODO Auto-generated method stubreturn 0;}}
public class User {}public class UserManagerSystem implements ManagerSystem<User>{@Overridepublic int add(User t) {// TODO Auto-generated method stubreturn 0;}@Overridepublic int remove(User t) {// TODO Auto-generated method stubreturn 0;}}
public class Book {}public class BookManagerSystem<T> implements ManagerSystem<T>{@Overridepublic int add(T t) {// TODO Auto-generated method stubreturn 0;}@Overridepublic int remove(T t) {// TODO Auto-generated method stubreturn 0;}}
public static void main(String[] args) {StudentManagerSystem sms = new StudentManagerSystem();sms.add(new Student());System.out.println("----------------------");UserManagerSystem ums = new UserManagerSystem();ums.add(new User());System.out.println("----------------------");BookManagerSystem<Book> bms01 = new BookManagerSystem<>();bms01.add(new Book());System.out.println("----------------------");BookManagerSystem<String> bms02 = new BookManagerSystem<>();bms02.add("Java从入门到精通");bms02.add("MySQL从删库到跑路");}

三、LinkedList

LinkedList的使用

1.ArrayList的方法都能用,但还有新的独有的方法:

public static void main(String[] args) {LinkedList<String> list = new LinkedList<>();list.add("希1");list.add("希2");list.add("希3");list.add("abc");list.add("abc");list.add("AAA");list.add("abc");list.add("abc");//添加到头部list.addFirst("aaa");list.offerFirst("bbb");list.push("ccc");//添加到末尾list.addLast("xxx");list.offer("yyy");list.offerLast("zzz");System.out.println("获取第一个元素:" + list.element());System.out.println("获取第一个元素:" + list.getFirst());System.out.println("获取第一个元素:" + list.peek());System.out.println("获取第一个元素:" + list.peekFirst());System.out.println("获取第一个元素:" + list.pop());System.out.println("获取最后一个元素:" + list.getLast());System.out.println("获取最后一个元素:" + list.peekLast());//删除第一个元素list.poll();list.pollFirst();list.removeFirst();//删除最后一个元素list.pollLast();list.removeLast();//删除第一次出现的元素list.removeFirstOccurrence("abc");//删除最后一次出现的元素list.removeLastOccurrence("abc");//倒序遍历
//		Iterator<String> descendingIterator = list.descendingIterator();
//		while(descendingIterator.hasNext()){
//			String next = descendingIterator.next();
//			System.out.println(next);
//		}for (String element : list) {System.out.println(element);}}

注意这里的descendingIterator迭代不是用hasPrevious()和previoues(),因为底层代码用的是hasPrevious()和previoues()来编写的,所以这里直接用next即可。

LinkdList实现队列模式

队列模式 - 先进先出

while(!list.isEmpty()){//String element = list.pollFirst();String element = list.removeFirst();System.out.println(element);}

栈模式 - 先进后出/后进先出

while(!list.isEmpty()){String element = list.removeLast();System.out.println(element);}

四、Vector与Stack

由于也是link下的分支,所以ArrayList的方法都能用。

独有方法:

Vector:

知识点:Vector老的方法
理解:Vector属于元老级别的集合类(JDK1.0),JDK1.2开始才有集合框架的概念,为了将Vector保留下来,Java的设计者让Vector多实现了List接口。

public static void main(String[] args) {Vector<String> v = new Vector<>();v.addElement("aaa");v.addElement("bbb");v.addElement("ccc");v.addElement("ddd");v.addElement("eee");v.removeElementAt(0);//根据下标删除元素v.removeElement("bbb");//根据数据删除元素Enumeration<String> elements = v.elements();while(elements.hasMoreElements()){String nextElement = elements.nextElement();System.out.println(nextElement);}}

Stack:

继承关系:class Stack extends Vector
特点:栈模式

LinkedListStack 都能实现栈模式,但 LinkedList 由于其实现了 Deque 接口,因此更加灵活和现代化。在现代 Java 开发中,推荐使用 LinkedListArrayDeque 来实现栈,以替代传统的 Stack 类。

public static void main(String[] args) {Stack<String> stack = new Stack<>();//将元素添加到栈顶stack.push("aaa");stack.push("bbb");stack.push("ccc");stack.push("ddd");stack.push("eee");System.out.println("获取栈顶元素:" + stack.peek());System.out.println("获取元素到栈顶的距离:" + stack.search("bbb"));//4 - 从1开始数//判断集合是否为空内容while(!stack.empty()){//删除栈顶元素,并返回String pop = stack.pop();System.out.println(pop);}}

五、HashSet与LinkedHashSet

HashSet的使用:

Link中所有和下标有关的方法均不可用。

HashSet set = new HashSet<>();

set.add(“abc”) - 添加数据

set.addAll(HashSet); - 将指定集合添加到集合的末尾

set.remove(“abc”) - 删除指定元素

set.removeAll(newSet); - 将list中有newSet的元素全部删除(删除交集)

set.retainAll(newset); - 将list中有newSet的元素保留,删除其他元素(保留交集)

int size = set.size(); - 获取元素的个数

set.clear(); - 清空集合里所有的元素

set.contains(“abc”) - 判断集合里是否包含指定元素,返回的是一个布尔值

set.containsAll(newSet); - 判断集合里是否包含指定集合,返回的是一个布尔值

set.isEmpty(); - 判断集合里有没有元素,返回的是一个布尔值

Object[] array1 = subSet.toArray();-将集合转换为数组

String[] array2 = subSet.toArray();- 将集合转换为指定类型的数组

遍历集合–foreach

for(String element:set){System.out.println(element);
}

遍历集合–Iterator

Iterator<String> it = set.iterator()
while(it.hasNext()){String next = it.next();System.out.println(next);
}

遍历集合 – ListIterator

ListIterator<String> listIterator = set.listIterator()
while(listIterator.hasNext()){String next = listIterator.next();System.out.println(next);
}

HashSet的特点

特点:无序且去重

添加步骤:
1.获取元素的hash值 – hashCode()
2.通过hash值计算在数组中的下标
3.判断下标上是否有元素
3.1 没有元素 – 直接添加
3.2 有元素 ---- 判断两个对象是否相同 hash && (==||equals())
3.2.1 相同 – 不添加数据(达到去重效果)
3.2.2 不相同 – 形成单向链表(JDK1.7头插法、JDK1.8尾插法)

遍历步骤:
遍历数组(顺序遍历)

注意:添加步骤处理数据的逻辑和遍历步骤处理数据的逻辑不一样,导致无序,但是哈希值相同的元素有序(在单向链表中)。

public static void main(String[] args) {HashSet<String> set = new HashSet<>();set.add("aaa");set.add("bbb");set.add("ccc");set.add("ccc");set.add("Aa");set.add("BB");for (String element : set) {System.out.println(element);//aaa Aa BB ccc bbb}}

LinkedHashSet的使用:

同HashSet。

HashSet的特点

继承关系:class LinkedHashSet extends HashSet
特点:有序且去重

添加步骤:
在父类HashSet的基础上,添加的元素会存储上一个元素的地址,
上一个元素也会存储下一个元素的地址 – 双向链表

遍历步骤:
找到第一个元素,再向下依次找下一个元素

注意:哈希值相同的元素依然存放在单向链表中,其余元素为双向。

public static void main(String[] args) {LinkedHashSet<String> set = new LinkedHashSet<>();set.add("aaa");set.add("bbb");set.add("ccc");set.add("ccc");set.add("Aa");set.add("BB");for (String element : set) {System.out.println(element);//aaa bbb ccc Aa BB}}

六、TreeSet

TreeSet的使用

同HashSet.

TreeSet的特点

特点:自然排序(TreeSet会根据不同的类型使用不同的排序规则)

public static void main(String[] args) {//TreeSet存储String -> 字典排序TreeSet<String> set1 = new TreeSet<>();set1.add("a");set1.add("c");set1.add("e");set1.add("bc");set1.add("bb");for (String element : set1) {System.out.println(element);}System.out.println("-----------------------------");//TreeSet存储Integer -> 数字升序TreeSet<Integer> set2 = new TreeSet<>();set2.add(3);set2.add(5);set2.add(1);set2.add(2);set2.add(4);for (Integer element : set2) {System.out.println(element);}}

知识点:内置比较器

public static void main(String[] args) {TreeSet<Student> set = new TreeSet<>();set.add(new Student("生希", '女', 29, "2402", "001"));            set.add(new Student("名空", '女', 23, "2402", "002"));            set.add(new Student("菜丽", '女', 25, "2402", "003"));            set.add(new Student("桐光", '女', 30, "2402", "004"));            set.add(new Student("岛玲", '女', 18, "2402", "005"));            set.add(new Student("井步", '女', 19, "2402", "006"));            set.add(new Student("奈奈", '女', 21, "2402", "007"));           set.add(new Student("悠亚", '女', 21, "2402", "008"));           set.add(new Student("朝阳", '女', 21, "2402", "009"));           set.add(new Student("亮", '男', 21, "2402", "010"));             set.add(new Student("从升", '男', 21, "2402", "011"));            set.add(new Student("小康", '男', 21, "2402", "012"));            set.add(new Student("伊织", '女', 21, "2403", "001"));           set.add(new Student("美莉", '女', 21, "2403", "002"));           set.add(new Student("咏美", '女', 21, "2403", "003"));           set.add(new Student("爱蜜莉", '女', 21, "2403", "004"));          set.add(new Student("绘里香", '女', 21, "2403", "005"));          set.add(new Student("满里惠", '女', 21, "2403", "006"));          set.add(new Student("Julia", '女', 21, "2403", "007"));        set.add(new Student("亮", '男', 24, "2403", "008"));             for (Student stu : set) {System.out.println(stu);}}
public class Student implements Comparable<Student>{private String name;private char sex;private int age;private String classId;private String id;public Student() {}public Student(String classId, String id) {this.classId = classId;this.id = id;}public Student(String name, char sex, int age, String classId, String id) {this.name = name;this.sex = sex;this.age = age;this.classId = classId;this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public char getSex() {return sex;}public void setSex(char sex) {this.sex = sex;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getClassId() {return classId;}public void setClassId(String classId) {this.classId = classId;}public String getId() {return id;}public void setId(String id) {this.id = id;}@Overridepublic boolean equals(Object obj) {if(this == obj){return true;}if(obj instanceof Student){Student stu = (Student) obj;if(classId.equals(stu.classId) && id.equals(stu.id)){return true;}}return false;}@Overridepublic String toString() {return name + "\t" + sex + "\t" + age + "\t" + classId + "\t" + id;}//排序规则:按照年龄排序@Overridepublic int compareTo(Student o) {return this.age - o.age;}

知识点:外置比较器

public class Test04 {
/**

  • 知识点:外置比较器
    */
    public static void main(String[] args) {
	TreeSet<Student> set = new TreeSet<>(new Comparator<Student>() {//排序规则:按照名字长度排序,名字长度一致按照年龄排序@Overridepublic int compare(Student o1, Student o2) {if(o1.equals(o2)){return 0;}int nameLen1 = o1.getName().length();int nameLen2 = o2.getName().length();if(nameLen1 != nameLen2){return nameLen1 - nameLen2;}int age1 = o1.getAge();int age2 = o2.getAge();if(age1 != age2){return age1 - age2;}return 1;}});set.add(new Student("生希", '女', 29, "2402", "001"));            set.add(new Student("名空", '女', 23, "2402", "002"));            set.add(new Student("菜丽", '女', 25, "2402", "003"));            set.add(new Student("桐光", '女', 30, "2402", "004"));            set.add(new Student("岛玲", '女', 18, "2402", "005"));            set.add(new Student("井步", '女', 19, "2402", "006"));            set.add(new Student("奈奈", '女', 21, "2402", "007"));           set.add(new Student("悠亚", '女', 21, "2402", "008"));           set.add(new Student("朝阳", '女', 21, "2402", "009"));           set.add(new Student("亮", '男', 21, "2402", "010"));             set.add(new Student("从升", '男', 21, "2402", "011"));            set.add(new Student("小康", '男', 21, "2402", "012"));            set.add(new Student("伊织", '女', 21, "2403", "001"));           set.add(new Student("美莉", '女', 21, "2403", "002"));           set.add(new Student("咏美", '女', 21, "2403", "003"));           set.add(new Student("爱蜜莉", '女', 21, "2403", "004"));          set.add(new Student("绘里香", '女', 21, "2403", "005"));          set.add(new Student("满里惠", '女', 21, "2403", "006"));          set.add(new Student("Julia", '女', 21, "2403", "007"));        set.add(new Student("亮", '男', 24, "2403", "008"));                          for (Student stu : set) {System.out.println(stu);}
}

小结:Collection接口下的集合类的特点

List接口下的集合 ---------------------------------------------------

ArrayList
数据结构:一维数组
特点:存储数据

LinkedList
数据结构:双向列表
特点:队列模式、栈模式

Vector
数据结构:一维数组
特点:线程安全

Stack
继承关系:class Stack extends Vector
特点:栈模式

Set接口下的集合 ------------------------------------------------------

HashSet
数据结构:hash表(一维数组)
特点:无序且不可重复

LinkedHashSet
继承关系:class LinkedHashSet extends HashSet
特点:有序且去重(添加了双向链表的数据结构)

TreeSet
数据结构:二叉树
特点:根据元素类型自然排序

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/841927.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微服务:eureka的搭建,以及服务注册、服务发现、负载均衡

eureka 搭建 新建一个Module,maven项目&#xff0c;导入依赖。 <dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency><…

月入10万+管道收益,揭秘旅游卡运营的5个阶段!

网上的项目确实繁多&#xff0c;只要深入研究&#xff0c;总能找到适合自己的赚钱方式。在互联网上运营&#xff0c;关键在于理解其底层逻辑。旅游卡项目&#xff0c;就是一个能实现月入10万的实例。接下来&#xff0c;我将为你揭密旅游卡运营的5个阶段&#xff1a; 1、先赚成…

24年湖南教资认定即将开始,别被照片卡审!

24年湖南教资认定即将开始&#xff0c;别被照片卡审&#xff01;

Jenkins 流水线(Pipeline)详解

大家好&#xff0c;Jenkins 流水线&#xff08;Pipeline&#xff09;是一种可编排的持续集成和交付&#xff08;CI/CD&#xff09;方法&#xff0c;它以代码的方式定义整个软件开发过程中的构建、测试和部署流程。接下来就跟大家分享一下Jenkins 流水线&#xff08;Pipeline&am…

2024年5月26日 (周日) 叶子游戏新闻

资深开发者&#xff1a;3A游戏当前处于一种尴尬的中间地带游戏行业整体&#xff0c;尤其是3A游戏正处于艰难时期。尽管2023年3A游戏佳作频出&#xff0c;广受好评&#xff0c;但居高不下的游戏开发成本&#xff08;传闻《漫威蜘蛛侠2》的制作成本高达3亿美元&#xff09;正严重…

【机器学习结合AI绘画工具】——开启艺术创作的新纪元

目录 一、AI绘画工具的发展历程 二、AI绘画工具的技术原理 实例说明 三、AI绘画工具在艺术创作中的应用 实例网站 四、AI绘画工具的影响与未来展望 结论 机器学习和人工智能&#xff08;AI&#xff09;在过去的十年里取得了显著的进展。特别是在艺术创作领域&#xff0c…

【笔记】太久没有写selenium了

以前qyqt和selenium用来开发一个自动化测试工具&#xff0c;现在回忆一下已经过了将近6年。 DeprecationWarning: find_element_by_* commands are deprecated. Please use find_element() 例如&#xff1a;find_element_by_xpath改为web.find_element(By.XPATH from seleniu…

excel表格写存神器--xlwt

原文链接&#xff1a;http://www.juzicode.com/python-tutorial-xlwt-excel 在 Python进阶教程m2d–xlrd读excel 中我们介绍了Excel表格的读取模块xlrd&#xff0c;今天这篇文章带大家了解Excel表格写存模块xlwt。他俩名字相近都以Excel的简写xl开头&#xff0c;rd是read的简写…

Java顺序表

Java顺序表 前言一、线性表介绍常见线性表总结图解 二、顺序表概念顺序表的分类顺序表的实现throw具体代码 三、顺序表会出现的问题 前言 推荐一个网站给想要了解或者学习人工智能知识的读者&#xff0c;这个网站里内容讲解通俗易懂且风趣幽默&#xff0c;对我帮助很大。我想与…

金融序列的布朗运动

https://zhuanlan.zhihu.com/p/659164160 python金融衍生品定价系列之一 —— 布朗运动与伊藤公式 导语:网络上和书本上关于期权定价相关的内容已经较为丰富,但将理论和python代码结合起来讲的却很少,这也是python金融衍生品定价系列的写作初衷,在用python实现相关模型的同…

Rating 计算公式

Rating ⁡ \operatorname{Rating} Rating 计算公式一般有多种&#xff0c;具体公式取决于使用情境和数据结构。 常用的环形排序算法的Rating计算公式是&#xff1a; Rating ⁡ R K ( P − E ) \operatorname{Rating} R K\times(P -E) RatingRK(P−E)其中&#xff0c; R …

春秋云境CVE-2018-20604

简介 雷风影视CMS是一款采用PHP基于THINKPHP3.2.3框架开发&#xff0c;适合各类视频、影视网站的影视内容管理程序&#xff0c;该CMS存在缺陷&#xff0c;可以通过 admin.php?s/Template/edit/path/*web*..*..*..*..*1.txt 的方式读取任意文件。 正文 1.进入靶场 2./admin…

AI学习指南数学工具篇-凸优化在支持向量机(SVM)中的应用

AI学习指南数学工具篇-凸优化在支持向量机&#xff08;SVM&#xff09;中的应用 在机器学习领域中&#xff0c;支持向量机&#xff08;SVM&#xff09;是一种经典的监督学习算法。SVM通过寻找最佳的超平面来进行分类&#xff0c;其优化核心是基于凸优化理论。本文将详细介绍凸…

【数据结构】二叉树-堆(上)

个人主页~ 二叉树-堆 一、树的概念及结构1、概念2、相关概念3、树的表示4、树的实际应用 二、二叉树的概念和结构1、概念2、特殊二叉树3、二叉树的性质4、二叉树的存储结构&#xff08;1&#xff09;顺序存储&#xff08;2&#xff09;链式存储 三、二叉树的顺序结构以及实现1、…

【C++】——入门基础知识超详解

目录 ​编辑 1.C关键字 2. 命名空间 2.1 命名空间定义 2.2 命名空间使用 命名空间的使用有三种方式&#xff1a; 注意事项 3. C输入&输出 示例 1&#xff1a;基本输入输出 示例 2&#xff1a;读取多个值 示例 3&#xff1a;处理字符串输入 示例 4&#xff1a;读…

Python并发编程大揭秘:打造你的多任务处理超能战队!

今天给大家带来的是学习如何构建一个能够同时处理海量任务的超级团队。从简单的线程和锁&#xff0c;到复杂的异步IO和多进程部署&#xff0c;每一个工具都像是你团队中的一员&#xff0c;各有所长&#xff0c;共同协作&#xff01; 文章目录 Python进阶之并发和并行编程详解1.…

【Linux-INPUT输入的子系统】

Linux-INPUT输入的子系统 ■ input 子系统简介■ input 驱动编写流程■ ■ input 子系统简介 input 子系统就是管理输入的子系统&#xff0c; input 子系统分为 input 驱动层、 input 核心层、 input 事件处理层&#xff0c;最终给用户空间提供可访问的设备节点 ■ input 驱…

leetcode打卡#day39 738. 单调递增的数字

738. 单调递增的数字 class Solution { public:int monotoneIncreasingDigits(int N) {string strNum to_string(N);// flag用来标记赋值9从哪里开始// 设置为这个默认值&#xff0c;为了防止第二个for循环在flag没有被赋值的情况下执行int flag strNum.size();for (int i …

【Linux-中断】

Linux-中断 ■■■ ■■■ ■■■ ■ ■ ■ ■ ■ ■ ■ ■ ■

React类组件生命周期详解

在React的类组件中&#xff0c;从组件创建到组件被挂载到页面中&#xff0c;这个过程react存在一系列的生命周期函数&#xff0c;最主要的生命周期函数是componentDidMount、componentDidUpdate、componentWillUnmount 生命周期图例如下 1. componentDidMount组件挂载 如果你…