Collections是什么
Collections(注意有个s)是一个工具类,全是静态方法,专门用来操作集合
就像 Arrays 是操作数组的工具类一样,Collections 是操作 Collection体系 的工具类
⚠️ 别跟 Collection(没有s,是接口)搞混了!
| 名称 |
类型 |
作用 |
Collection |
接口 |
集合的顶层接口,定义了add/remove/contains等方法 |
Collections |
工具类 |
提供排序、查找、同步等静态工具方法 |
排序相关:sort / reverse / shuffle
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| @Test public void testSortAndShuffle() { List<Integer> list = new ArrayList<>(Arrays.asList(3, 1, 4, 1, 5, 9, 2, 6));
Collections.sort(list); System.out.println("升序:" + list);
Collections.sort(list, Collections.reverseOrder()); System.out.println("降序:" + list);
Collections.reverse(list); System.out.println("反转:" + list);
Collections.shuffle(list); System.out.println("洗牌:" + list); }
|
自定义对象排序
1 2 3 4 5 6 7 8 9 10 11 12
| @Test public void testCustomSort() { List<String> names = new ArrayList<>(Arrays.asList("张三", "李四", "王五", "赵六"));
Collections.sort(names, (a, b) -> a.length() - b.length()); System.out.println(names);
names.sort(Comparator.comparingInt(String::length)); System.out.println(names); }
|
查找相关:max / min / frequency
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| @Test public void testSearchMethods() { List<Integer> list = Arrays.asList(3, 1, 4, 1, 5, 9, 2, 6);
System.out.println("最大值:" + Collections.max(list));
System.out.println("最小值:" + Collections.min(list));
System.out.println("1出现了几次:" + Collections.frequency(list, 1));
List<Integer> sorted = new ArrayList<>(list); Collections.sort(sorted); int index = Collections.binarySearch(sorted, 5); System.out.println("5的下标:" + index); }
|
不可修改集合:unmodifiableList / unmodifiableMap
把一个普通集合”冻住”,变成只读的,任何修改操作都抛 UnsupportedOperationException
适合用在返回内部数据时,防止外部代码乱改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| @Test public void testUnmodifiable() { List<String> original = new ArrayList<>(Arrays.asList("A", "B", "C"));
List<String> readOnly = Collections.unmodifiableList(original);
System.out.println(readOnly.get(0));
original.add("D"); System.out.println(readOnly);
Map<String, Integer> map = new HashMap<>(); map.put("key", 1); Map<String, Integer> readOnlyMap = Collections.unmodifiableMap(map);
}
|
线程安全包装:synchronizedList / synchronizedMap
给普通集合套上 synchronized 锁,变成线程安全版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @Test public void testSynchronized() {
List<String> syncList = Collections.synchronizedList(new ArrayList<>()); syncList.add("A"); syncList.add("B");
Map<String, Integer> syncMap = Collections.synchronizedMap(new HashMap<>()); syncMap.put("key", 1);
synchronized (syncList) { for (String s : syncList) { System.out.println(s); } } }
|
⚠️ 实际开发中更推荐用 java.util.concurrent 包下的并发集合:
CopyOnWriteArrayList 替代 synchronizedList
ConcurrentHashMap 替代 synchronizedMap(详见 Map体系)
特殊集合:emptyList / singletonList
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| @Test public void testSpecialCollections() {
List<String> empty = Collections.emptyList(); System.out.println(empty); System.out.println(empty.size());
List<String> single = Collections.singletonList("唯一元素"); System.out.println(single);
Map<String, Integer> emptyMap = Collections.emptyMap(); Set<String> emptySet = Collections.emptySet(); }
|
其他实用方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| @Test public void testOtherMethods() { List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C", "D", "E"));
Collections.swap(list, 0, 4); System.out.println("交换后:" + list);
Collections.fill(list, "X"); System.out.println("填充后:" + list);
List<String> copies = Collections.nCopies(5, "Hello"); System.out.println(copies);
List<Integer> listA = Arrays.asList(1, 2, 3); List<Integer> listB = Arrays.asList(4, 5, 6); List<Integer> listC = Arrays.asList(3, 4, 5); System.out.println(Collections.disjoint(listA, listB)); System.out.println(Collections.disjoint(listA, listC));
List<String> colors = new ArrayList<>(Arrays.asList("红", "绿", "红", "蓝")); Collections.replaceAll(colors, "红", "黄"); System.out.println(colors); }
|
常用方法速查表
| 方法 |
作用 |
注意点 |
sort(list) |
升序排序 |
可传Comparator自定义 |
reverse(list) |
反转顺序 |
不是排序,单纯倒过来 |
shuffle(list) |
随机打乱 |
洗牌算法 |
max(collection) |
最大值 |
|
min(collection) |
最小值 |
|
frequency(collection, obj) |
出现次数 |
|
binarySearch(list, key) |
二分查找 |
list必须已排序 |
unmodifiableList(list) |
不可修改包装 |
原list改了它也变 |
synchronizedList(list) |
线程安全包装 |
遍历仍需手动同步 |
emptyList() |
空集合 |
不可修改 |
singletonList(obj) |
单元素集合 |
不可修改 |
swap(list, i, j) |
交换两个位置 |
|
fill(list, obj) |
全部替换 |
|
disjoint(c1, c2) |
是否无交集 |
|
常见坑
坑1:binarySearch之前忘了排序
Collections.binarySearch() 要求List必须是已排序的,否则结果不可预测
坑2:以为unmodifiable是深拷贝
unmodifiableList(original) 只是个包装,修改original还是会影响到它
想真正不可变,用 List.copyOf()(Java10+)或手动深拷贝
坑3:synchronizedList遍历不加锁
虽然单个操作(add/get)是线程安全的,但遍历时还是可能被其他线程修改
遍历必须手动 synchronized(syncList) { ... }