JavaSE9️⃣集合 - Collection 体系
Collection:存储单值。
1、List 接口
有序,有下标,可重复
Vector 类 | ArrayList 类 | LinkedList 类 | |
---|---|---|---|
Java 版本 | 1.0 | 1.2 | 1.2 |
存储结构 | 数组 | 数组 | 双向链表 |
线程安全 | ✔ | ❌ | ❌ |
1.1、成员方法
在
Collection
接口的基础上,添加了与下标有关方法、列表迭代器。
1.1.1、常用方法
- add(int, E)、remove():指定位置插入/删除。
- get()、set():指定位置读/写。
- indexOf()、lastIndexOf():获取元素首次/最后一次出现的下标。
- listIterator():列表迭代器(比 iterator 功能更强大)。
- subList():子集,左闭右开
1.1.2、remove()
当集合中存放整数类型,调用
remove()
时:需要区分是 “按下标删除” 还是 “按元素删除”。
-
按下标:传递基本类型。
list.remove(0);
-
按元素:传递引用类型。
list.remove((Object) 0); list.remove((Integer) 0);
1.1.3、equals()
equals()
是 Object 类定义的方法。具体说明 👉 浅谈 equals() 和 hashCode()
-
默认实现:比较两个对象引用是否指向同一内存地址。
public class Object { public boolean equals(Object obj) { return (this == obj); } }
-
重写:
- 为不同对象重写
equals()
方法,自定义比较规则。 - 通常认为两个对象的属性值完全相同,则对象相等。
- 为不同对象重写
1.2、遍历方式
以 ArrayList 为例,4 种遍历方式。
-
for:
ArrayList<Person> list = new ArrayList<>(); for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); }
-
增强 for:
for (Person person : list) { System.out.println(person); }
-
迭代器:
Iterator<Person> iterator = list.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); }
-
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+
引入新的实现类和迭代器。
ArrayList
和LinkedList
:线程不安全、性能更高(👉 源码:ArrayList & LinkedList)。Iterator
:改善方法名称、支持删除操作(👉 设计模式:迭代器)。
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 种遍历方式。
-
增强 for:
HashSet<Person> set = new HashSet<>(); for (Person person : set) { System.out.println(person); }
-
迭代器:
Iterator<Person> iterator = set.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
1.2、实现类
1.2.1、HashSet
HashSet 本质:HashMap + 冗余 value。
-
map:实际存储元素的结构(HashMap)。
-
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。
-
m:实际存储元素的结构(TreeMap 实现自 NavigableMap)。
-
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:
- HashSet:成对重写
hashcode()
和equals()
。 - TreeMap:基于
compareTo()
比较,与hashCode()
和equals()
无关。- Comparable 接口实现类
- Comparator 匿名内部类