Java 集合
Java 集合类用于存储对象,可以实现常用的数据结构。
一、集合概述
1. 什么是集合?
集合类又称容器类,主要用于保存数据。
2. 集合类与数组的区别
数组:
长度固定
元素既可以是基本类型,也可以是引用类型
只能存储同一类型的数据
集合类:
- 长度可变
- 元素仅能是引用类型(的指针)
- 可以存储不同类型数据
3. 集合的分类
集合可以分为两大类:
Collection:用于存储数量不等的数据
List:有序、可重复的列表
- ArrayList:基于动态数组实现;支持随机访问
- Vector:与 ArrayList 类似,但线程安全
- LinkedList:基于双向链表实现;只能顺序访问
Set:无序、不可重复的集合
TreeSet:基于红黑树实现;支持 o(logN) 级查找;支持有序性操作
HashSet:基于哈希表实现;支持 o(1) 级查找;不支持有序性操作
LinkedHashSet:与 HashSet 相比,支持了有序性操作
Queue:队列
- ArrayDeque:基于循环数组实现
- PriorityQueue:基于堆实现;可以作为优先队列
Map:用于储存键值对
HashMap:基于哈希表实现
LinkedHashMap:与 HashMap 相比,维护了键的顺序
TreeMap:基于红黑树实现
Hashtable:与 HashMap 类似,但线程安全;遗留类,不应再使用
ConcurrentHashMap:线程安全,且效率更高
引入了分段锁
二、Collection
1. 什么是 Collection?
Collection 接口是 List、Set、Queue 接口的父接口,该接口中的方法可以用于操作 List、Set、Queue 集合。
2. 集合方法
Collection 接口中有以下方法:
方法 | 说明 |
---|---|
add(Object obj) | 向集合中添加指定元素 |
remove(Object obj) | 从集合中删除指定元素 |
clear() | 清空集合所有元素 |
contains(Object obj) | 判断集合中是否有指定元素 |
isEmpty() | 判断集合是否为空 |
iterator() | 返回一个 Iterator 对象,用于遍历集合 |
size() | 返回集合的元素个数 |
toArray() | 将集合以数组形式返回 |
三、Collections
1. 说明
Collections 是一个用于操作 Set、List、Map 等集合的工具类,该工具类中提供了对于集合的操作方法。
2. 对 List 的方法
方法 | 说明 |
---|---|
reverse(list) | 反转 list 中元素的顺序 |
shuffle(list) | 对 list 中的元素进行随机排序 |
sort(list[, comparator]) | 对 list 进行自然排序或指定排序 |
swap(List, index1, index2) | 将 list 中 index1 和 index2 的元素进行交换 |
rotate(list, distance) | 当 distance 为正时,将后 distance 个元素移到前面;当 distance 为负时,将前 distance 个元素移到后面 |
binarySearch(list, obj) | 用二分法查找指定元素,要求 list 有序 |
fill(list, obj) | 用指定元素填满 list |
indexOfSubList(list, subList) | 返回 subList 在 list 中第一次出现的位置 |
lastIndexOfSubList(list, subList) | 返回 subList 在 list 中最后一次出现的位置 |
replaceAll(list, oldVal, newVal) | 用 newVal 替换 list 中的 oldVal |
3. 对 Collections 的方法
方法 | 说明 |
---|---|
max(collection[, comparator]) | 根据自然排序或指定排序,返回 collection 中的最大元素 |
min(collection[, comparator]) | 根据自然排序或指定排序,返回 collection 中的最小元素 |
frequency(collection, obj) | 返回 obj 在 collection 中的出现次数 |
4. synchronizedXxx()
Collections 类中提供了多个 synchronizedXxx()
方法,用于将指定集合包装成线程同步的集合,从而可以解决多线程并发访问集合时的线程安全问题。
1 |
|
1
2
3
4
5
6
7
public class Test {
public static void main(String[] args) {
List list = Collections.synchronizedList(new ArrayList());
Set set = Collections.synchronizedSet(new HashSet());
Map map = Collections.synchronizedMap(new HashMap());
}
}
5. 不可变集合
(1) 常用方法
Collections 提供了用于获取不可变集合的方法。
方法 | 说明 |
---|---|
emptyXxx() | 返回一个空的、不可变的集合 |
singletonXxx(obj) | 返回一个只包含指定对象、不可变的集合 |
unmodifiableXxx(collection) | 返回指定集合的不可变版本 |
(2) Java 9 新增
可以通过类方法 of(obj, obj, ···, obj)
创建具有若干个指定元素的不可变集合。
1 |
|
1
2
3List list = List.of(obj, obj, ···, obj);
Set set = Set.of(obj, obj, ···, obj);
Map map = Map.of(obj, obj, ···, obj);
四、迭代器
1. 什么是迭代器?
Iterator,又称为迭代器,可以用于遍历实现了 Iterable 接口的对象。
2. 说明
方法 | 说明 |
---|---|
hasNext() | 判断是否有下一个元素 |
next() | 返回集合中下一个元素 |
remove() | 删除上一个 next() 返回的元素 |
forEachRemaining(Consumer action) | 用 Lambda 表达式遍历集合 |
1
2
3
4
Iterator iterator = 集合名.iterator();
while (iterator.hasNext()) {
···iterator.next()···
}
五、Stream 流
1. 什么是 Stream 流?
Stream 流是 Java8 中添加了一个新的接口类,相当于高级版的 Iterator。
Stream 流将元素集合看作一种流,通过一系列处理得到最终的结果。
2. 创建 Stream 流
(1) 直接创建
创建 Stream 的 builder,再通过 add()
方法增加元素,最后调用 build()
方法创建 Stream 流。
1 |
|
(2) 通过 Collection 创建
1 |
|
(3) 通过 Map 创建
首先通过 Map 的方法获得 Collection实例,然后再创建 Stream 流。
1 |
|
(4) 通过数组创建
通过 Stream 的静态方法 of()
创建
1 |
|
3. 处理 Stream 流
方法 | 说明 |
---|---|
filter(Predicate predicate) | 过滤所有不符合 predicate 的元素 |
limit(long maxSize) | 只保留前 maxSize 个元素 |
skip(long discardNum) | 丢弃前 discardNum 个元素 |
concat(Stream stream1, Stream stream2) | 合并 stream1 和 stream2 |
distinct() | 过滤,相同的元素只保留一个 |
sorted([Comparator comparator]) | 排序,自然排序或通过 comparator 排序 |
map(Function function) | 返回将 function 应用于每个元素之后的 Stream 流 |
4. 终结 Steam 流
调用以下方法后,Stream 流将终结。
方法 | 说明 |
---|---|
foreach(Consumer consumer) | 遍历元素,对每个元素执行 consumer |
toArray() | 转换为数组 |
count() | 返回流中的元素个数 |
5. 示例
1 |
|
六、List
具体请看:
七、Queue
具体请看:
八、Map
具体请看:
九、Set
具体请看:
参考
疯狂 Java 讲义