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 return
        int lastRet = -1; // index of last element returned; -1 if no such

        // To track modifications to the list during iteration
        int expectedModCount = modCount;

        // Checks if the list has more elements
        @Override
        public boolean hasNext() {
            return cursor != size();
        }

        // Returns the next element in the iteration
        @SuppressWarnings("unchecked")
        @Override
        public 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
        @Override
        public 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 iteration
        final 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 - 1
    private 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;       // 游标 - 4
        int lastRet = -1; // 当前元素的下标 - 3
        int expectedModCount = modCount;//内部操作数 - 6

        public boolean hasNext() {
            return cursor != size;//4 != 4
        }

        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification();//判断外部操作数和内部操作数是否相同
            int i = cursor;//i = 3
            if (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 - 4
            return (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 traffic
            cursor = 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 - 6
				it.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>{

	@Override
	public int add(Student t) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int remove(Student t) {
		// TODO Auto-generated method stub
		return 0;
	}

}
public class User {

}

public class UserManagerSystem implements ManagerSystem<User>{

	@Override
	public int add(User t) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int remove(User t) {
		// TODO Auto-generated method stub
		return 0;
	}

}
public class Book {

}

public class BookManagerSystem<T> implements ManagerSystem<T>{

	@Override
	public int add(T t) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int remove(T t) {
		// TODO Auto-generated method stub
		return 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;
	}
	
	@Override
	public 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;
	}

	@Override
	public String toString() {
		return name + "\t" + sex + "\t" + age + "\t" + classId + "\t" + id;
	}

	//排序规则:按照年龄排序
	@Override
	public 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>() {

		//排序规则:按照名字长度排序,名字长度一致按照年龄排序
		@Override
		public 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
数据结构:二叉树
特点:根据元素类型自然排序

  • 19
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
代码下载:完整代码,可直接运行 ;运行版本:2022a或2019b或2014a;若运行有问题,可私信博主; **仿真咨询 1 各类智能优化算法改进及应用** 生产调度、经济调度、装配线调度、充电优化、车间调度、发车优化、水库调度、三维装箱、物流选址、货位优化、公交排班优化、充电桩布局优化、车间布局优化、集装箱船配载优化、水泵组合优化、解医疗资源分配优化、设施布局优化、可视域基站和无人机选址优化 **2 机器学习和深度学习方面** 卷积神经网络(CNN)、LSTM、支持向量机(SVM)、最小二乘支持向量机(LSSVM)、极限学习机(ELM)、核极限学习机(KELM)、BP、RBF、宽度学习、DBN、RF、RBF、DELM、XGBOOST、TCN实现风电预测、光伏预测、电池寿命预测、辐射源识别、交通流预测、负荷预测、股价预测、PM2.5浓度预测、电池健康状态预测、水体光学参数反演、NLOS信号识别、地铁停车精准预测、变压器故障诊断 **3 图像处理方面** 图像识别、图像分割、图像检测、图像隐藏、图像配准、图像拼接、图像融合、图像增强、图像压缩感知 **4 路径规划方面** 旅行商问题(TSP)、车辆路径问题(VRP、MVRP、CVRP、VRPTW等)、无人机三维路径规划、无人机协同、无人机编队、机器人路径规划、栅格地图路径规划、多式联运运输问题、车辆协同无人机路径规划、天线线性阵列分布优化、车间布局优化 **5 无人机应用方面** 无人机路径规划、无人机控制、无人机编队、无人机协同、无人机任务分配 **6 无线传感器定位及布局方面** 传感器部署优化、通信协议优化、路由优化、目标定位优化、Dv-Hop定位优化、Leach协议优化、WSN覆盖优化、组播优化、RSSI定位优化 **7 信号处理方面** 信号识别、信号加密、信号去噪、信号增强、雷达信号处理、信号水印嵌入提取、肌电信号、脑电信号、信号配时优化 **8 电力系统方面** 微电网优化、无功优化、配电网重构、储能配置 **9 元胞自动机方面** 交通流 人群疏散 病毒扩散 晶体生长 **10 雷达方面** 卡尔曼滤波跟踪、航迹关联、航迹融合

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值