JavaSE9️⃣集合 - Collection 体系

Collection:存储单值

image-20220302233359176

1、List 接口

有序,有下标,可重复

Vector 类 ArrayList 类 LinkedList 类
Java 版本 1.0 1.2 1.2
存储结构 数组 数组 双向链表
线程安全

1.1、成员方法

Collection 接口的基础上,

添加了与下标有关方法列表迭代器

image-20220303233549955

1.1.1、常用方法

  1. add(int, E)、remove():指定位置插入/删除。
  2. get()、set():指定位置读/写。
  3. indexOf()、lastIndexOf():获取元素首次/最后一次出现的下标。
  4. listIterator():列表迭代器(比 iterator 功能更强大)。
  5. subList():子集,左闭右开

1.1.2、remove()

当集合中存放整数类型,调用 remove() 时:

需要区分是 “按下标删除” 还是 “按元素删除”。

  1. 按下标:传递基本类型。

    list.remove(0);
    
  2. 按元素:传递引用类型。

    list.remove((Object) 0);
    list.remove((Integer) 0);
    

1.1.3、equals()

equals()Object 类定义的方法。

具体说明 👉 浅谈 equals() 和 hashCode()

  1. 默认实现:比较两个对象引用是否指向同一内存地址

    public class Object {
        public boolean equals(Object obj) {
            return (this == obj);
        }
    }
    
  2. 重写

    1. 为不同对象重写 equals() 方法,自定义比较规则。
    2. 通常认为两个对象的属性值完全相同,则对象相等

1.2、遍历方式

以 ArrayList 为例,4 种遍历方式。

  1. for

    ArrayList<Person> list = new ArrayList<>();
    
    for (int i = 0; i < list.size(); i++) {
        System.out.println(list.get(i));
    }
    
  2. 增强 for

    for (Person person : list) {
        System.out.println(person);
    }
    
  3. 迭代器

    Iterator<Person> iterator = list.iterator();
    
    while (iterator.hasNext()) {
        System.out.println(iterator.next());
    }
    
  4. list 迭代器:向后、向前

    ListIterator<Person> listIterator = list.listIterator();
    
    // 向后
    while(listIterator.hasNext()){
        System.out.println(listIterator.next());
    }
    // 向前
    while(listIterator.hasPrevious()){
        System.out.println(listIterator.previous());
    

1.3、实现类

Java 1.0

  • Vector:大量方法使用了 synchronized(线程安全、性能差)。
  • Enumeration(枚举器):遍历集合。

Java 1.2+

引入新的实现类和迭代器。

2、Set 接口

无序,无下标,不可重复

HashSet 类 TreeSet 接口
(SortedSet 实现类)
LinkedHashSet 类
(HashSet 子类)
Java 版本 1.2 1.2 1.4
存储结构 HashMap 红黑树 链表
线程安全
元素去重原理 基于 hashCode 基于排列顺序 基于 hashCode
说明 判断相等:先 hashCode(),再 equals() 对集合元素自动排序(需实现 Comparable 接口) 保留元素的插入顺序(默认升序)

相比 List 接口,Set 没有下标的概念。

因此没有定义关于下标的方法,所有方法均实现 Collection 接口。

1.1、遍历方式

List 和 Set 遍历方式对比

List Set 说明
for 有下标才能使用
增强 for -
迭代器 -
list 迭代器 仅 List 中定义

以 HashSet 为例,2 种遍历方式。

  1. 增强 for

    HashSet<Person> set = new HashSet<>();
    
    for (Person person : set) {
        System.out.println(person);
    }
    
  2. 迭代器

Iterator<Person> iterator = set.iterator();

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

1.2、实现类

1.2.1、HashSet

HashSet 本质HashMap + 冗余 value

  1. map:实际存储元素的结构(HashMap)。

  2. PRESENT:冗余数据,作为 HashMap 的 value。

    private transient HashMap<E,Object> map;
    private static final Object PRESENT = new Object();
    
    public HashSet() {
        map = new HashMap<>();
    }
    
    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }
    

1.2.2、TreeSet

TreeSet 本质TreeMap + 冗余 value

  1. m:实际存储元素的结构(TreeMap 实现自 NavigableMap)。

  2. PRESENT:冗余数据,作为 TreeMap 的 value。

    private transient NavigableMap<E,Object> m;
    private static final Object PRESENT = new Object();
    
    
    TreeSet(NavigableMap<E,Object> m) {
        this.m = m;
    }
    public TreeSet() {
        this(new TreeMap<E,Object>());
    }
    
    public boolean add(E e) {
        return m.put(e, PRESENT)==null;
    }
    

1.2.3、本质

Set 集合本质:相应的 Map + 冗余 value。

Hint

  1. HashSet:成对重写 hashcode()equals()
  2. TreeMap:基于 compareTo() 比较,与 hashCode()equals() 无关。
    • Comparable 接口实现类
    • Comparator 匿名内部类
posted @ 2023-03-15 00:32  Jaywee  阅读(18)  评论(0编辑  收藏  举报

👇