← 返回题目列表

Collections 工具类有哪些常用方法?它和 Collection 是什么关系?

简单 第 17 / 30 题 更新于 2026/07/27
Collections工具类排序同步包装

简化版

Collections(注意有 s)是一个工具类——里面全是静态方法,用来操作集合(排序、查找、同步包装、不可变包装等);它和 Collection(无 s,是所有集合的顶层接口)是完全不同的东西:Collection 是接口(集合的抽象),Collections 是工具类(操作集合的静态方法)。常用方法分几类:① 排序查找sort 排序、binarySearch 二分查找、reverse 反转、shuffle 打乱、max/min 最值);② 同步包装synchronizedList/Map 给集合套一层同步壳,变线程安全);③ 不可变包装unmodifiableList/Map 返回只读视图);④ 空集合/单元素emptyListsingletonList)。类似的还有 Arrays 工具类(操作数组)。

详细版

Collection vs Collections

CollectionCollections
是什么接口(集合的顶层抽象)工具类(java.util.Collections)
内容定义集合的方法(add/remove/size…)全是静态方法(操作集合)
用法被 List/Set 等继承实现Collections.sort(list) 直接调静态方法

Collections 常用方法分类

List<Integer> list = new ArrayList<>(List.of(3, 1, 2));

// ① 排序、查找、重排
Collections.sort(list);                    // 排序 → [1, 2, 3]
Collections.sort(list, Comparator.reverseOrder());  // 自定义排序
Collections.binarySearch(list, 2);         // 二分查找(需已排序)
Collections.reverse(list);                 // 反转 → [3, 2, 1]
Collections.shuffle(list);                 // 随机打乱
Collections.swap(list, 0, 1);              // 交换两个位置
int max = Collections.max(list);           // 最大值
int min = Collections.min(list);           // 最小值
int cnt = Collections.frequency(list, 2);  // 统计元素出现次数

// ② 同步包装(变线程安全)
List<Integer> syncList = Collections.synchronizedList(list);   // 线程安全的 List
Map<K,V> syncMap = Collections.synchronizedMap(map);

// ③ 不可变包装(只读视图)
List<Integer> readOnly = Collections.unmodifiableList(list);   // 只读,改会抛异常

// ④ 空集合 / 单元素集合
List<Integer> empty = Collections.emptyList();                 // 空的不可变 List
List<Integer> single = Collections.singletonList(1);           // 只有一个元素的不可变 List

// ⑤ 批量操作
Collections.fill(list, 0);                 // 全部填充为 0
Collections.addAll(list, 1, 2, 3);         // 批量添加

⚠️ 别把 Collections(工具类,有 s)Collection(接口,无 s) 搞混——这是常见混淆点。Collection 是 List/Set/Queue 的父接口(定义集合的行为);Collections 是操作集合的工具类(全是静态方法)。类比:Arrays(工具类)操作 Array(数组)。记忆:带 s 的是工具类(一堆工具方法)、不带 s 的是接口

完整版教学

一、Collections 是什么:操作集合的工具箱

Collectionsjava.util 包下的一个工具类——它不是集合,而是「一堆操作集合的静态方法的集合」:

Collections 的定位:
  它本身是个 final 类,构造器私有(不能 new)
  里面全是 static 方法(Collections.sort(list) 这样直接调)
  作用:提供操作集合的通用算法(排序、查找、同步、不可变等)

为什么要有它:
  很多集合操作是通用的(排序、查找最值、反转...)
  与其在每个集合类里都写一遍,不如集中到一个工具类
  → Collections 就是"集合的通用算法工具箱"

Collections 体现了「工具类模式」——把「不属于某个具体集合、但操作集合的通用算法」集中到一个静态工具类。它和 Arrays(操作数组的工具类)、Objects(操作对象的工具类)、Math(数学工具类)是同类。使用时直接 Collections.方法名(集合)。理解「Collections 是操作集合的静态工具类、集中通用算法」,就理解了它的定位——它是「工具箱」不是「容器」。

二、Collection vs Collections:接口 vs 工具类

这是最常见的混淆点,必须分清——Collection(无 s)和 Collections(有 s)是完全不同的东西

Collection(接口,无 s):
  是集合框架的顶层接口之一
  Collection ← List/Set/Queue ← ArrayList/HashSet...
  定义集合的基本行为:add/remove/size/contains/iterator...
  用法:作为类型声明(Collection<String> c = new ArrayList<>())

Collections(工具类,有 s):
  是 java.util.Collections 工具类
  全是静态方法:sort/binarySearch/synchronizedList/unmodifiableList...
  用法:调静态方法(Collections.sort(list))

一个是"集合的抽象接口",一个是"操作集合的工具方法",毫无继承关系

区分记忆:「s」代表「一堆方法(工具类)」,没「s」代表「一个接口」。类比 Array(数组)vs Arrays(数组工具类)、Object(对象)vs Objects(对象工具类)——带 s 的都是「操作前者的工具类」。理解「Collection 是集合接口、Collections 是集合工具类、带 s 是工具类」,就永远不会搞混这两个——这是个高频的「细节考点」。

三、排序、查找与重排

Collections 最常用的是排序、查找、重排这类算法方法:

// 排序(对 List,元素要可比较或传 Comparator)
Collections.sort(list);                              // 自然排序(元素实现 Comparable)
Collections.sort(list, Comparator.comparing(User::getAge));  // 自定义排序
// 注:List 自己也有 sort 方法(list.sort(...)),Java 8+ 推荐用 list.sort

// 查找
Collections.binarySearch(list, key);   // 二分查找(前提:list 已按相同规则排序!)
Collections.max(list);                 // 最大值(元素可比较)
Collections.min(list);                 // 最小值

// 重排
Collections.reverse(list);             // 反转顺序
Collections.shuffle(list);             // 随机打乱(洗牌,如随机排序)
Collections.rotate(list, 2);           // 循环移位
Collections.swap(list, i, j);          // 交换两个位置的元素

要点:sort 要求元素可比较(实现 Comparable)或传 ComparatorbinarySearch 必须先排序(对未排序的 List 用二分查找结果不可靠);max/min/sort 底层用元素的比较规则。注意 Java 8+ 后 List 接口自己有了 sort 方法(list.sort(comparator)),比 Collections.sort 更面向对象、推荐用。shuffle 常用于「随机排序」(如抽奖、洗牌)。理解「Collections 的排序查找重排方法、sort 需可比较、binarySearch 需先排序」,就掌握了它最常用的一类方法。

四、同步包装:给集合加线程安全

CollectionssynchronizedXxx 方法能「给一个非线程安全的集合套一层同步壳,变成线程安全的」(前面「线程安全的 List」题讲过):

List<String> list = new ArrayList<>();                     // 非线程安全
List<String> syncList = Collections.synchronizedList(list); // 线程安全(同步包装)
Map<K,V> syncMap = Collections.synchronizedMap(new HashMap<>());
Set<E> syncSet = Collections.synchronizedSet(new HashSet<>());

// 原理:返回一个包装类,每个方法用 synchronized 包住再委托给原集合

原理是「装饰器模式」——synchronizedList 返回一个包装对象,它的每个方法都用 synchronized 加锁后再委托给原集合,从而线程安全。但有两个必须知道的点(前面详讲过):① 遍历时要手动加锁(迭代器方法没被同步,synchronized(syncList){ 遍历 });② 复合操作不原子if (!contains) add 这类组合仍需外层加锁)。它是「同步容器」(一把锁串行化),性能不如并发容器(CopyOnWriteArrayList/ConcurrentHashMap)。理解「synchronizedXxx 给集合加同步壳(装饰器)、遍历要手动锁、复合操作不原子」,就掌握了这类方法——但记住它是「老式同步容器」,现代并发用 JUC 的并发容器。

五、不可变包装与空集合

Collections 还提供「不可变包装」和「空/单元素集合」:

// 不可变包装:返回只读视图(改会抛 UnsupportedOperationException)
List<String> readOnly = Collections.unmodifiableList(list);
readOnly.add("x");   // ✗ 抛 UnsupportedOperationException

// 空集合(不可变、可复用的空集合单例)
List<String> empty = Collections.emptyList();      // 空 List(不可变)
Map<K,V> emptyMap = Collections.emptyMap();
Set<E> emptySet = Collections.emptySet();

// 单元素集合(不可变)
List<String> one = Collections.singletonList("x");  // 只有一个元素的不可变 List
Map<K,V> oneEntry = Collections.singletonMap(k, v);

不可变包装(unmodifiableXxx 返回原集合的「只读视图」——不能增删改(抛异常),但注意它是「视图」(原集合改了它也变,且它只是「禁止通过这个视图改」不是「深度不可变」)。空集合(emptyList 等) 返回可复用的不可变空集合单例(比 new ArrayList<>() 省内存,适合返回「空结果」)。单元素集合(singletonList 等) 返回只含一个元素的不可变集合(比 List.of(x) 更老的写法)。这些常用于「返回空/单个结果」「防止方法返回的集合被外部修改」。理解「unmodifiableXxx 只读视图、emptyXxx 可复用空集合、singletonXxx 单元素集合」,就掌握了这类「特殊集合」方法。(Java 9+ 的 List.of() 提供了更好的真不可变集合,见「不可变集合」题。)

六、Collections 与相关工具类

Collections 是「集合工具类」,Java 里还有几个平行的工具类,一起记:

工具类操作对象常用方法
Collections集合(Collection)sort/binarySearch/synchronizedXxx/unmodifiableXxx/emptyXxx
Arrays数组(Array)sort/binarySearch/asList/copyOf/fill/equals/stream
Objects对象(Object)equals/hashCode/requireNonNull/isNull/toString
Math数值max/min/abs/round/pow/random

这些工具类的共同点是「静态方法的集合、操作某类数据、构造器私有不能 new」。Collections(集合)和 Arrays(数组)尤其对应——一个操作集合、一个操作数组,方法名很多都对应(sort/binarySearch 都有)。记住「带 s 的工具类操作某类数据」,就能把它们串起来。实践中:操作集合找 Collections、操作数组找 Arrays、判空/equals 找 Objects。理解「Collections/Arrays/Objects/Math 是平行的工具类、各操作一类数据」,就把工具类体系理清了。

记忆钩子:「Collections(有 s)是操作集合的静态工具类,别和 Collection(无 s,集合接口)混(带 s=工具类、无 s=接口,类比 Array/Arrays);常用方法:排序查找重排(sort/binarySearch 需先排序/reverse/shuffle/max/min)、同步包装(synchronizedList 加同步壳,遍历要手动锁)、不可变包装(unmodifiableList 只读视图)、空/单元素集合(emptyList/singletonList);平行工具类 Arrays 操作数组、Objects 操作对象」

七、常见误区与追问

  • 误区:Collection 和 Collections 是一个东西。 完全不同——Collection(无 s)是集合的顶层接口(List/Set 的父接口),Collections(有 s)是操作集合的静态工具类;带 s 是工具类、无 s 是接口。
  • 误区:Collections.binarySearch 对任意 List 都能用。 必须先排序——二分查找要求 List 已按相同规则排序,对未排序的 List 用二分查找结果不可靠(可能找不到存在的元素)。
  • 误区:Collections.synchronizedList 遍历也是线程安全的。 遍历时要手动加锁(synchronized(syncList){迭代})——迭代器方法没被同步,否则并发修改仍抛 CME;且复合操作不原子。
  • 误区:unmodifiableList 返回的是独立的不可变副本。 是原集合的「只读视图」——原集合改了它也变,且只是禁止通过这个视图修改;要真不可变副本用 List.copyOf 或 new ArrayList 复制。
  • 追问:Collection 和 Collections 的区别? Collection 是接口(集合的顶层抽象、定义 add/remove 等行为、被 List/Set 实现),Collections 是工具类(java.util.Collections、全是操作集合的静态方法如 sort/synchronizedList)。
  • 追问:Collections 有哪些常用方法? 排序查找重排(sort/binarySearch/reverse/shuffle/max/min/swap)、同步包装(synchronizedList/Map/Set)、不可变包装(unmodifiableXxx)、空/单元素集合(emptyList/singletonList)、批量(fill/addAll)。
  • 追问:Collections.synchronizedList 的原理和注意点? 装饰器模式——返回包装对象,每个方法用 synchronized 加锁再委托原集合;注意遍历要手动加锁(迭代器未同步)、复合操作不原子、性能不如并发容器。

八、加强记忆

Collections有 s)是操作集合的静态工具类(final、构造器私有、全是 static 方法),它和 Collection无 s,是 List/Set/Queue 的顶层接口)是完全不同的东西——带 s 是工具类、无 s 是接口(类比 Array/ArraysObject/Objects)。Collections 常用方法分四类:① 排序查找重排sort 排序(元素需可比较或传 Comparator,Java 8+ 推荐 list.sort)、binarySearch 二分查找(必须先排序)、reverse/shuffle/rotate/swap/max/min/frequency);② 同步包装synchronizedList/Map/Set 装饰器加同步壳变线程安全,但遍历要手动加锁、复合操作不原子,是老式同步容器不如 JUC 并发容器);③ 不可变包装unmodifiableList 返回只读视图——原集合改了它也变,不是真副本);④ 空/单元素集合emptyList/singletonList 返回可复用的不可变集合,用于返回空/单个结果)。平行工具类:Arrays(数组)、Objects(对象)、Math(数值)。一句话「Collections 是集合工具类(有 s,别和 Collection 接口混)、方法有排序查找(binarySearch 需先排序)/同步包装(遍历要手动锁)/不可变视图/空集合,平行的 Arrays 操作数组」。