Java 集合collection详解 | 「掘金日新计划 · 10 月更文挑战」

104 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天

一、本篇笔记重点内容:

  • Collection接口方法
  • Iterator迭代器接口
  • Collection子接口:List
  • Collection子接口:Set接口

二、详细知识点介绍:

Collection接口方法

在这里插入图片描述

* 向Collection接口的实现类的对象中添加数据obj时,要求obj所在类要重写equals().
//1.contains(Object obj):判断当前集合中是否包含obj
//在判断时会调用obj对象所在类的equals()。
 coll.add(123);
 System.out.println(coll.contains(new Person("Jerry",20)));//false -->true
@Override
    public boolean equals(Object o) {
        System.out.println("Person equals()....");
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age &&
                Objects.equals(name, person.name);
    }
 //把123放入new对象所在类的equals方法形参

Iterator迭代器接口

内部方法:hasnext()和next() 调用后者前要用前者检测下一条记录是否有效,否则直接调用next()会抛出NoSuchElementException异常

  • 使用Iterator遍历collection
while(iterator.hasNext()){
            System.out.println(iterator.next());
        }

错误方式一: nosuchelementexception空指针、间隔输出

      Iterator iterator = coll.iterator();
      while(iterator.next() != null){
          System.out.println(iterator.next());
      }

错误方式二: 死循环,每次实例化后都会生成一个指向容器顶部的iterator指针

while(coll.iterator().hasNext()){
    System.out.println(coll.iterator().next());
}

Collection子接口:List

List接口的实现类常用的有:ArrayList、LinkedList和Vector

  • |----ArrayList:作为List接口的主要实现类;线程不安全的,效率高;底层使用Object[] elementData存储

  • |----LinkedList:对于频繁的插入、删除操作,使用此类效率比ArrayList高;底层使用双向链表存储

  • |----Vector:作为List接口的古老实现类;线程安全的,效率低;底层使用Object[] elementData存储

jdk 8中ArrayLis底层 :变长数组 Object[] elementData初始化为{},第一次调用add时才创建了一个长度为10的数组。扩容方面:默认扩容为原来的容量的1.5倍,同时需要将原有数组中的数据复制到新的数组中

LinkedList底层:双向链表,内部没有声明数组,而是定义了Node类型的first和last,用于记录首末元素。同时,定义内部类Node,作为LinkedList中保存数据的基本结构。

vector底层:大多数操作与ArrayList相同,区别之处在于Vector是线程安全的。扩容方面:默认扩容为原来数组的两倍。

增强for循环在这里插入图片描述 List接口常用方法 在这里插入图片描述

Collection子接口:Set接口

  • |----Set接口:存储无序的、不可重复的数据 -->“集合”
  • |----HashSet:作为Set接口的主要实现类;线程不安全的;可以存储null值
  • |----LinkedHashSet:作为HashSet的子类;遍历其内部数据时,可以按照添加的顺序遍历。对于频繁的遍历操作,LinkedHashSet效率高于HashSet.
  • |----TreeSet:可以按照添加对象的指定属性,进行排序。

向hashset中添加元素的过程在这里插入图片描述

添加过程注释

  • 若此位置已有其他元素(或以链表形式存在多个),则比较元素的hash值:存在hash值不同但通过某种算法被分为同一索引位置的可能。(注:如果使用率超过0.75,底层数组会扩容为原来的二倍)。
  • 如果hash值相同,需要调用元素a所在类的equals()方法: 存在由于hashcode计算方法设计出现的偶然情况(两个截然不同的实例有可能在逻辑上是相等的),如 a.name=jack (1) a.age=13(2) hashcode 1+2=3 b.name=ann(2) b.age=32(1) hashcode 2+1=3
    通过equals来判断name和age是否相等 ~ 所以重写的hashCode()和equals()需要尽可能保持一致性: 相等的对象必须具有相等的散列码。

HashSet 集合判断两个元素相等的标准: 两个对象通过hashCode() 方法比较相等,并且两个对象的equals()方法返回值也相等。

三、引用参考&推荐书目: