on java8之集合

1. 集合分类

在这里插入图片描述在这里插入图片描述在这里插入图片描述

2. 没有使用泛型的集合


    public static void main(String[] args) {
    
    
        ArrayList strs=new ArrayList<>();
        strs.add("123");
        strs.add("145");
        strs.add(789);
        for(Object o:strs){
    
    
           String s=(String)o;
           System.out.println(s.indexOf("1"));
        }
    }

上面代码在本来是要添加字符串类型的,但是不小心添加了一个整数,这样当后面强转为字符串类型时就会报错
在这里插入图片描述


3. 使用泛型的集合

public static void main(String[] args) {
    
    
        ArrayList<String> strs=new ArrayList<>();
        strs.add("123");
        strs.add("145");
        // strs.add(789);//编译报错  不能添加整型
        for(String s:strs){
    
    
           System.out.println(s.indexOf("1"));
        }
    }

通过使用泛型,就可以在编译期防止将错误类型的对象放置到集合中


4. 一次性添加多个元素

 public static void main(String[] args) {
    
    
        Collection<Integer> collection = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
        Integer[] moreInts = {
    
     6, 7, 8, 9, 10 };
        collection.addAll(Arrays.asList(moreInts));
        // Runs significantly faster, but you can't
        // construct a Collection this way:
        Collections.addAll(collection, 11, 12, 13, 14, 15);
        Collections.addAll(collection, moreInts);
        // Produces a list "backed by" an array:
        List<Integer> list = Arrays.asList(16, 17, 18, 19, 20);
        list.set(1, 99); // OK -- modify an element
        // list.add(21); // Runtime error; the underlying
        // array cannot be resized.
    }

Collection是一个接口, Collections一个工具类,可以对Collection类的对象进行多种操作

Arrays.asList() 的输出作为一个 List ,但是这里的底层实现是数组,没法调整大小。如果尝试在这个List 上调用 add() 或 remove(),由于这两个方法会尝试修改数组大小,所以会在运行时得到 “Unsupported Operation(不支持的操作)” 错误


5. Collection接口中的方法

通用方法,只有某个类实现了 Collection接口,比如ArrayList和LinkedList

  1. 添加: add(Object obj) addAll(Collection coll)
  2. 获取有效元素的个数: int size()
  3. 清空集合:void clear()
  4. 是否是空集合: boolean isEmpty()
  5. 是否包含某个元素:boolean contains(Object obj):是通过元素的equals方法来判断是否是同一个对象
  6. 是否包含某些元素:boolean containsAll(Collection c):也是调用元素的equals方法来比较的。拿两个集合的元素挨个比较
  7. 删除单个元素:boolean remove(Object obj) :通过元素的equals方法判断是否是要删除的那个元素。只会删除找到的第一个元素
  8. 删除一些元素:boolean removeAll(Collection coll)
  9. 取两个集合的交集:boolean retainAll(Collection c):把交集的结果存在当前集合中,不影响c
  10. 集合是否相等: boolean equals(Object obj)
  11. 转成对象数组: Object[] toArray()
  12. 获取集合对象的哈希值: hashCode()
  13. 遍历: 返回迭代器对象,用于集合遍历

6. 迭代器

迭代器是一个对象,它在一个序列中移动并选择该序列中的每个对象,而客户端程序员不知道或不关心该序列的底层结构

迭代器的作用:

  1. 使用 iterator() 方法要求集合返回一个 Iterator。Iterator 将准备好返回序列中的第一个元素
  2. 使用 next() 方法获得序列中的下一个元素
  3. 使用 hasNext() 方法检查序列中是否还有元素(最开始指针指向第一个元素的前一个位置
  4. 使用 remove() 方法将迭代器最近返回的那个元素删除

在使用迭代器时不能调用集合的添加或删除方法:

在这里插入图片描述
在这里插入图片描述

可以使用迭代器自身的删除方法:

  public static void main(String[] args) {
    
    
        ArrayList<Integer> list=new ArrayList<>();
        list.addAll(Arrays.asList(1,2,3,4,5));
        Iterator<Integer> it=list.iterator();
        while(it.hasNext()){
    
    
            System.out.println(it.next());
            it.remove();
        }
        System.out.println(list);//[]
    }

如果还未调用next()或在上一次调用 next 方法之后已经调用了 remove 方法,再调用remove都会报IllegalStateException 也就是说上面代码中的remove调用需要在next方法调用之后

for-each迭代
遍历集合的底层调用Iterator完成操作, 注意使用forEach迭代的同时改变引用变量是不影响原集合的

  public static void main(String[] args) {
    
    
        String[] strs=new String[3];
        for(String s:strs){
    
    
            s="123";
        }
        System.out.println(Arrays.toString(strs));//[null, null, null]
    }

7. 列表List

List 承诺将元素保存在特定的序列中。List 接口在 Collection 的基础上添加了许多方法,允许在 List 的中间插入和删除元素

  • ArrayList ,擅长随机访问元素,但在 List 中间插入和删除元素时速度较慢
  • LinkedList ,它通过代价较低的在 List 中间进行的插入和删除操作,提供了优化的顺序访问。LinkedList 对于随机访问来说相对较慢,但它具有比 ArrayList更大的特征集

List除了从Collection集合继承的方法外,List 集合里添加了一些根据索引来,操作集合元素的方法
List接口中的方法:

  • void add(int index, Object ele):在index位置插入ele元素
  • boolean addAll(int index, Collection eles):从index位置开始将eles中的所有元素添加进来
  • Object get(int index):获取指定index位置的元素
  • int indexOf(Object obj):返回obj在集合中首次出现的位置
  • int lastIndexOf(Object obj):返回obj在当前集合中末次出现的位置
  • Object remove(int index):移除指定index位置的元素,并返回此元素
  • Object set(int index, Object ele):设置指定index位置的元素为ele
  • List subList(int fromIndex, int toIndex):返回从fromIndex到toIndex位置的子集合

LinkedList常用方法:

  • getFirst() 和 element() 是相同的,它们都返回列表的头部(第一个元素)而并不删除它,如果 List 为空,则抛出 NoSuchElementException 异常。peek()方法与这两个方法只是稍有差异,它在列表为空时返回 null
  • removeFirst() 和 remove() 也是相同的,它们删除并返回列表的头部元素,并在列表为空时抛出 NoSuchElementException 异常。poll() 稍有差异,它在列表为空时返回 null
  • addFirst() 在列表的开头插入一个元素
  • offer() 与 add() 和 addLast() 相同。它们都在列表的尾部(末尾)添加一个元素
  • removeLast() 删除并返回列表的最后一个元素

使用LinkedList模拟栈: :

  • 入栈:addFirst(x);
  • 出栈:removeFirst();
  • 取栈顶元素: getFirst();

使用LinkedList模拟队列: :

  • 入队:addLast(x);
  • 出队:removeFirst();
  • 取队首元素: getFirst();

使用LinkedList模拟双端队列: :

  • 队尾添加:addLast(x);
  • 队首添加:addFirst(x);
  • 队首出队:removeFirst();
  • 队尾出队:removeLast() ;
  • 取队首元素: getFirst()
  • 取队尾元素: getLast()

8. 栈

Java 1.0 中附带了一个 Stack 类,结果设计得很糟糕(为了向后兼容,我们永远坚持 Java 中的旧设计错误)。Java 6 添加了 ArrayDeque ,其中包含直接实现堆栈功能的方法。

 public static void main(String[] args) {
    
    
         Deque<Integer> stack=new ArrayDeque<>();
         stack.push(1);
         stack.push(2);
         stack.push(3);
         stack.pop();
         System.out.println(stack.peek());
    }

9. 集合Set

Set 不保存重复的元素。如果试图将相同对象的多个实例添加到 Set 中,那么它会阻止这种重复行为。
Set 具有与 Collection 相同的接口,因此没有任何额外的功能,不像前面两种不同类型的 List 那样。实际上,Set 就是一个 Collection ,只是行为不同

9.1 HashSet

  • 不能保证元素的排列顺序
  • HashSet 不是线程安全的
  • 集合元素可以是 null
  • HashSet 集合判断两个元素相等的标准:两个对象通过 hashCode() 方法比较相等,并且两个对象的 equals() 方法返回值也相等
  • 对于存放在Set容器中的对象,对应的类一定要重写equals()和hashCode(Object obj)方法,以实现对象相等规则。即:“相等的对象必须具有相等的散列码”

HashSet的添加过程:

在这里插入图片描述

  1. 计算添加进来的对象的hash值,根据hash值进行映射,映射到某个位置(该位置上可以有多个元素,多个元素以链表形式连接)
  2. 如果某个元素的hash值对应的位置上面已经有元素,则遍历链表比较,如果遇到一个元素使用equals比较相同,添加失败;找不到相同的,添加成功。

重写 hashCode() 方法的基本原则:

  • 在程序运行时,同一个对象多次调用 hashCode() 方法应该返回相同的值
  • 当两个对象的 equals() 方法比较返回 true 时,这两个对象的 hashCode()方法的返回值也应相等
  • 对象中用作 equals() 方法比较的 Field,都应该用来计算 hashCode 值

9.2 LinkedHashSet

  • LinkedHashSet 是 HashSet 的子类
  • LinkedHashSet 根据元素的 hashCode 值来决定元素的存储位置,但它同时使用双向链表维护元素的次序,这使得元素看起来是以插入顺序保存的
  • LinkedHashSet插入性能略低于 HashSet,但在迭代访问 Set 里的全部元素时有很好的性能
  • LinkedHashSet 不允许集合元素重复

9.3 TreeSet

  • TreeSet 是 SortedSet 接口的实现类,TreeSet 可以确保集合元素处于排序状态
  • TreeSet底层使用红黑树结构存储数据
  • 添加到TreeSet接口中的元素要么实现了Comparable接口,要么实现了Compartor接口
class Student implements Comparable<Student>{
    
    
    String name;
    int score;
    public Student(String name,int score){
    
    
        this.name=name;
        this.score=score;
    }
	@Override
	public int compareTo(Student stu) {
    
    
		// TODO Auto-generated method stub
		return this.score-stu.score;//按分数升序
	}
    public String toString(){
    
    
        return "name: "+name+"  score: "+score;
    }

}
public class Drawing {
    
    
    public static void main(String[] args) {
    
    
        TreeSet<Student> stus=new TreeSet<>();
        stus.add(new Student("Tom",97));
        stus.add(new Student("Bob",95));
        stus.add(new Student("Mary",93));
        System.out.println(stus);

    }
}

class Student{
    
    
    String name;
    int score;
    public Student(String name,int score){
    
    
        this.name=name;
        this.score=score;
    }
    public String toString(){
    
    
        return "name: "+name+"  score: "+score;
    }

}
public class Drawing {
    
    
    public static void main(String[] args) {
    
    
        TreeSet<Student> stus=new TreeSet<>(new Comparator<Student>() {
    
    

			@Override
			public int compare(Student o1, Student o2) {
    
    
				// TODO Auto-generated method stub
				return o2.score-o1.score;//按分数降序
			}
            
        });
        stus.add(new Student("Tom",97));
        stus.add(new Student("Bob",95));
        stus.add(new Student("Mary",93));
        System.out.println(stus);

    }
}

当同时实现了两个接口时,Comparator接口的优先级较高


10. Map接口

  • Map与Collection并列存在。用于保存具有映射关系的数据:key-value
  • Map 中的 key 和 value 都可以是任何引用类型的数据
  • Map 中的 key 用Set来存放,不允许重复,即同一个 Map 对象所对应的类,须重写hashCode()和equals()方法
  • 常用String类作为Map的“键“

常用方法:

  • Object put(Object key,Object value):将指定key-value添加到(或修改)当前map对象中
  • void putAll(Map m):将m中的所有key-value对存放到当前map中
  • Object remove(Object key):移除指定key的key-value对,并返回value
  • void clear():清空当前map中的所有数据
  • Object get(Object key):获取指定key对应的value
  • boolean containsKey(Object key):是否包含指定的key
  • boolean containsValue(Object value):是否包含指定的value
  • int size():返回map中key-value对的个数
  • boolean isEmpty():判断当前map是否为空
  • boolean equals(Object obj):判断当前map和参数对象obj是否相等
  • Set keySet():返回所有key构成的Set集合
  • Collection values():返回所有value构成的Collection集合
  • Set entrySet():返回所有key-value对构成的Set集合

10.1 HashMap

  • HashMap是 Map 接口使用频率最高的实现类
  • 允许使用null键和null值,与HashSet一样,不保证映射的顺序
  • 所有的key构成的集合是Set:无序的、不可重复的。所以,key所在的类要重写:equals()和hashCode()
  • 所有的value构成的集合是Collection:无序的、可以重复的。所以,value所在的类要重写:equals()
  • 一个key-value构成一个entry
  • 所有的entry构成的集合是Set:无序的、不可重复的
  • HashMap 判断两个 key 相等的标准是:两个 key 通过 equals() 方法返回 true,hashCode 值也相等
  • HashMap 判断两个 value相等的标准是:两个 value 通过 equals() 方法返回 true
  public static void main(String[] args) {
    
    
        HashMap<String,Integer> map=new HashMap<>();
        map.put("A", 65);
        map.put("B", 66);
        map.put("C", 67);
        //遍历key
        for(String key:map.keySet()){
    
    
            System.out.println("key: "+key);
        }
        //遍历value
        for(Integer value:map.values()){
    
    
            System.out.println("value: "+value);
        }
        //遍历key和value
        for(Entry<String,Integer> entry:map.entrySet()){
    
    
            System.out.println("key: "+entry.getKey()+" value:"+entry.getValue());
        }
    }

10.2 LinkedHashMap

  • LinkedHashMap 是 HashMap 的子类
  • 在HashMap存储结构的基础上,使用了一对双向链表来记录添加元素的顺序
  • 与LinkedHashSet类似,LinkedHashMap 可以维护 Map 的迭代顺序:迭代顺序与 Key-Value 对的插入顺序一致

10.3 TreeMap

  • TreeMap存储 Key-Value 对时,需要根据 key-value 对进行排序。TreeMap 可以保证所有的 Key-Value 对处于有序状态
  • TreeSet底层使用红黑树结构存储数据
  • 和TreeSet一样,TreeMap需要实现Comparable接口或Comparator接口之一
  • 如果两个key是两个不同的对象,只要这两个对象的比较的结果相同(不是地址比较),就认为是一个key

11. Collections类中的常用方法

Collections 是一个操作 Set、List 和 Map 等集合的工具类

均为static方法

  1. reverse(List):反转 List 中元素的顺序
  2. shuffle(List):对 List 集合元素进行随机排序
  3. sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序
  4. sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序
  5. swap(List,int, int):将指定 list 集合中的 i 处元素和 j 处元素进行交换
  6. Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
  7. Object max(Collection,Comparator):根据 Comparator 指定的顺序,返回给定集合中的最大元素
  8. Object min(Collection)
  9. Object min(Collection,Comparator)
  10. int frequency(Collection,Object):返回指定集合中指定元素的出现次数
  11. void copy(List dest,List src):将src中的内容复制到dest中
  12. boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换List 对象的所有旧值

猜你喜欢

转载自blog.csdn.net/qq_43478694/article/details/126578282