Collections 是 JDK 提供的一个工具类,位于 java.util 包下,提供了一系列的静态方法,方便我们对集合进行各种操作。
/**
* @author QHJ
* @date 2022/11/11 14:39
* @description: CollectionsTest1
*/
public class CollectionsTest1 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("青花椒1");
list.add("青花椒2");
list.add("青花椒3");
list.add("青花椒4");
list.add("青花椒5");
System.out.println("原始顺序:" + list); // 原始顺序:[青花椒1, 青花椒2, 青花椒3, 青花椒4, 青花椒5]
// 反转
Collections.reverse(list);
System.out.println("反转后:" + list); // 反转后:[青花椒5, 青花椒4, 青花椒3, 青花椒2, 青花椒1]
// 洗牌
Collections.shuffle(list);
System.out.println("洗牌后:" + list); // 洗牌后:[青花椒2, 青花椒4, 青花椒5, 青花椒3, 青花椒1]
// 自然升序
Collections.sort(list);
System.out.println("自然升序后:" + list); // 自然升序后:[青花椒1, 青花椒2, 青花椒3, 青花椒4, 青花椒5]
// 交换
Collections.swap(list, 2,4);
System.out.println("交换后:" + list); // 交换后:[青花椒1, 青花椒2, 青花椒5, 青花椒4, 青花椒3]
}
}
/**
* @author QHJ
* @date 2022/11/11 14:43
* @description: CollectionsTest2
*/
public class CollectionsTest2 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("青花椒1");
list.add("青花椒2");
list.add("青花椒3");
list.add("青花椒4");
list.add("青花椒5");
System.out.println("最大元素:" + Collections.max(list)); // 最大元素:青花椒5
System.out.println("最小元素:" + Collections.min(list)); // 最小元素:青花椒1
System.out.println("出现的次数:" + Collections.frequency(list, "青花椒2")); // 出现的次数:1
// 没有排序直接调用二分查找,结果是不确定的
System.out.println("排序前的二分查找结果:" + Collections.binarySearch(list, "青花椒2")); // 排序前的二分查找结果:1
// 排序后,查找结果和预期一致
Collections.sort(list);
System.out.println("排序后的二分查找结果:" + Collections.binarySearch(list, "青花椒2")); // 排序后的二分查找结果:1
// 使用指定对象填充
Collections.fill(list, "青花椒6");
System.out.println("填充后的结果:" + list); // 填充后的结果:[青花椒6, 青花椒6, 青花椒6, 青花椒6, 青花椒6]
}
}
HashMap 是线程不安全的,ArrayList 其实也是线程不安全的,没法在多线程环境下使用,那 Collections 工具类中提供了多个 synchronizedXxx 方法,这些方法会返回一个同步的对象,从而解决多线程中访问集合时的安全问题。

List<String> list = new ArrayList<>();
list.add("青花椒1");
list.add("青花椒2");
list.add("青花椒3");
list.add("青花椒4");
list.add("青花椒5");
List<String> synchronizedList = Collections.synchronizedList(list);
扒一下 SynchronizedList 的源码:
static class SynchronizedList<E>
extends SynchronizedCollection<E>
implements List<E> {
private static final long serialVersionUID = -7754090372962971524L;
final List<E> list;
SynchronizedList(List<E> list) {
super(list);
this.list = list;
}
public E get(int index) {
synchronized (mutex) {return list.get(index);}
}
public void add(int index, E element) {
synchronized (mutex) {list.add(index, element);}
}
public E remove(int index) {
synchronized (mutex) {return list.remove(index);}
}
}
其实就是在方法上加了 synchronized 关键字来加锁保证线程的安全。
举个例子,我要在空的不可变集合中添加一个元素:
List emptyList = Collections.emptyList();
emptyList.add("非空");
System.out.println(emptyList);
这段代码在执行的时候就会报错:

这是因为 Collections.emptyList() 会返回一个 Collections 的内部类 EmptyList,而EmptyList 并没有重写父类 AbstractList 的 add(int index, E element) 方法,所以执行的时候就抛出了不支持该操作的 UnsupportedOperationException 了。
除此之外,emptyList 方法是 final 的,返回的 EMPTY_LIST 也是 final 的,这就表明这是个不可变对象,没办法进行增删改查。
@SuppressWarnings("unchecked")
public static final <T> List<T> emptyList() {
return (List<T>) EMPTY_LIST;
}
public static final List EMPTY_LIST = new EmptyList<>();
还有两个比较常用的方法:
/**
* @author QHJ
* @date 2022/11/11 15:08
* @description:
*/
public class CollectionsTest4 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("青花椒1");
list.add("青花椒2");
list.add("青花椒3");
list.add("青花椒4");
list.add("青花椒5");
List<String> allList = new ArrayList<>();
Collections.addAll(allList, "青花椒6", "青花椒7", "青花椒8");
System.out.println("addAll 后:" + allList); // addAll 后:[青花椒6, 青花椒7, 青花椒8]
System.out.println("是否没有交集:" + (Collections.disjoint(list, allList) ? "是" : "否")); // 是否没有交集:是
}
}
推荐二哥的文章:https://tobebetterjavaer.com/common-tool/hutool.html。
推荐二哥的文章:https://tobebetterjavaer.com/common-tool/guava.html。