Java 中的 Collection
Java 中的集合包括三大类,分别是 Set(集)、List(列表)、Map(映射),它们都位于 java.util
包下,Set、List 和 Map 都是接口,各有各自的实现类。Set 的常用实现类有 TreeSet 和 HashSet,List 的常用实现类有 ArrayList 和 LinkedList,Map 的常用实现类有 HashMap 和 TreeMap 等。
Collection
Collection 是最基本的集合接口,声明了适用于 Java 集合的通用方法,Set 和 List 都继承自 Collection 接口。
1 | ---|Collection<E> |
下面是 Collection 接口中一些常用的 API:
Return Type | Method | Description |
---|---|---|
boolean | add(E e) | 确保集合中包含指定的元素 |
boolean | addAll(Collection<? extends E> c) | 将指定集合中的所有元素添加到此集合中 |
void | clear() | 从此集合中删除所有元素 |
boolean | contains(Object o) | 如果此集合中包含指定的元素则返回 true |
boolean | containsAll(Collection<?> c) | 如果此集合包含指定集合中的所有元素则返回 true |
boolean | isEmpty() | 如果此集合不包含元素则返回 true |
Iterator |
iterator() | 返回此集合中的元素的迭代器 |
boolean | remove(Object o) | 从此集合中删除指定元素 |
boolean | removeAll(Collection<?> c) | 从此集合中删除指定集合包含的所有元素 |
int | size() | 返回此集合中的元素数量 |
Object[] | toArray() | 返回一个包含此集合中所有元素的数组 |
Set
Set 具有与 Collection 完全一样的接口,因此没有任何额外的功能。实际上 Set 就是 Collection,只是行为不同。
Set: 存入 Set 的每个元素都必须是唯一的,因为 Set 不保存重复元素。加入 Set 的元素必须重写 equals() 方法以确保对象的唯一性。Set 接口不保证维护元素的次序。
TreeSet: 保存次序的 Set,底层为树结构。使用它可以从Set中提取有序的序列。
HashSet: 为快速查找设计的 Set。存入 HashSet 的对象必须重写 hashCode() 方法。
List
List: 次序是 List 最大的特点,它保证元素可以按照特定的顺序排列。下面是 List 新增的一些常用 API:
Return Type | Method | Description |
---|---|---|
boolean | add(E e) | 将指定元素添加到此列表的末尾 |
void | add(int index, E element) | 将指定元素添加到此列表中的指定位置 |
E | get(int index) | 返回此列表中指定位置的元素 |
int | indexOf(Object o) | 返回此列表中指定元素第一次出现的索引,如果此列表不包含该元素则返回 -1 |
int | lastIndexOf(Object o) | 返回此列表中指定元素最后一次出现的索引,如果此列表不包含该元素则返回 -1 |
E | remove(int index) | 从此列表中删除指定位置的元素 |
boolean | remove(Object o) | 从此列表中删除第一次出现的指定元素 |
E | set(int index, E element) | 用指定的元素替换此列表中指定位置的元素 |
void | sort(Comparator<? super E> c) | 使用 Comparator 比较器将此列表中的元素重新排序 |
ArrayList: 由数组实现的 List,实现了随机访问的接口,允许对元素进行快速随机访问,但是向 List 中间插入与移除元素的速度比较慢。
LinkedList: 基于链表实现的 List,对顺序访问进行了优化,向 List 中间插入与删除的开销并不大,但随机访问则相对较慢。除了上面的方法以外 LinkedList 还有下列常用 API:
Return Type | Method | Description |
---|---|---|
boolean | add(E e)/offer(E e) | 将指定元素添加到此列表的末尾 |
void/boolean/void | addFirst(E e)/offerFirst(E e)/push(E e) | 在此列表开头插入指定的元素 |
void/boolean | addLast(E e)/offerLast(E e) | 将指定的元素追加到此列表的末尾 |
E | getFirst() | 返回此列表中的第一个元素 |
E | getLast() | 返回此列表中的最后一个元素 |
E | removeFirst()/pop() | 删除并返回此列表中第一个元素 |
E | removeLast() | 删除并返回此列表中最后一个元素 |
如果对于 LinkedList 中多个方法都是同一个功能感到疑惑,看一下 LinkedList 的源码你就懂了:
1 | package java.util; |
小结
集合 | 使用场景 | 线程安全 | 可否添加 null |
---|---|---|---|
Set | 不需要保留存储顺序,并且需要去掉重复元素 | ||
TreeSet | 需要将元素排序 | × | × |
HashSet | 不需要将元素排序 | × | √ |
List | 需要保留存储顺序,并且保留重复元素 | ||
ArrayList | 查询多,增删少 | × | √ |
LinkedList | 增删多,查询少 | × | √ |
Map
Map 是一种使用「键值对」的方式来存储数据的集合,每个「键」映射一个「值」,可以通过「键」来获取对应的「值」。下面是 Map 接口中常用的一些 API:
Return Type | Method | Description |
---|---|---|
void | clear() | 删除该 Map 中所有的映射 |
boolean | containsKey(Object key) | 如果此 Map 包含指定键的映射,则返回 true |
boolean | containsValue(Object value) | 如果此 Map 将一个或多个键映射到指定的值,则返回 true |
V | get(Object key) | 返回此 Map 指定键对应的值,如果不存在返回 null |
Set |
keySet() | 返回此 Map 中包含的键的 Set 集合 |
V | put(K key, V value) | 将指定的值与指定键相关联 |
V | remove(Object key) | 从此 Map 中删除指定键的映射 |
int | size() | 返回此 Map 中键值映射的数量 |
Collection |
values() | 返回此 Map 中包含的值的 Collection 集合 |
HashMap: 基于散列表的实现。插入和查询「键值对」的开销是固定的。
TreeMap: 基于红黑树数据结构的实现。查看「键」或「键值对」时,它们会被排序(次序由 Comparabel 或 Comparator 决定)。TreeMap 的特点在于,得到的结果是经过排序的。TreeMap 是唯一的带有 subMap() 方法的 Map,它可以返回一个子树。
Hashtable: 和 HashMap 一样也是一个散列表,不过它的函数都是同步的,这意味着它是线程安全的。它的 key、value 都不可以为 null。此外,Hashtable 中的映射不是有序的。
小结
Map | 使用场景 | 线程安全 | 键可否为 null | 值可否为 null |
---|---|---|---|---|
HashMap | 适用于 Map 中插入、删除和定位元素 | × | √ | √ |
TreeMap | 适用于按自然顺序或自定义顺序遍历键(key) | × | × | √ |
Hashtable | 适用于多线程时保证线程安全 | √ | × | × |