Skip to content

Collections 工具类

概述

Collectionsjava.util 包中针对集合(List、Set、Map 等)的工具类,提供大量静态方法,用于排序、查找、填充、同步包装、不可变视图以及空集合等常见操作。日常开发中,直接使用这些方法可以避免手写循环、减少出错,并统一处理线程安全与不可变需求。


基本用法

Collections 的所有方法都是静态方法,通过类名直接调用:

java
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;

List<String> list = new ArrayList<>(List.of("C", "A", "B"));
Collections.sort(list);   // 原地排序
// list 变为 [A, B, C]

常用方法可按用途分为:排序与打乱查找与极值不可变与空集合同步包装其他工具。下面按类目说明并给出示例。


排序与打乱

sort / reverse / shuffle

方法说明
sort(List<T> list)按元素自然顺序升序排序(元素需实现 Comparable
sort(List<T> list, Comparator<? super T> c)按指定 Comparator 排序
reverse(List<?> list)反转列表顺序(原地)
shuffle(List<?> list)随机打乱列表顺序
java
List<String> list = new ArrayList<>(List.of("banana", "apple", "cherry"));

// 自然顺序(字典序)排序
Collections.sort(list);
// list: [apple, banana, cherry]

// 反转
Collections.reverse(list);
// list: [cherry, banana, apple]

// 随机打乱(可用于洗牌、随机抽样等)
Collections.shuffle(list);

自定义排序时使用 Comparator

java
// 按字符串长度排序
Collections.sort(list, Comparator.comparingInt(String::length));

// 降序
Collections.sort(list, Comparator.reverseOrder());

提示

基本类型 的 List(如 List<Integer>),sort(list) 按数值大小排序;对自定义类,需实现 Comparable<T> 或传入 Comparator。详见 常用类 中的比较与排序。


查找与极值

binarySearch / min / max

方法说明
binarySearch(List<? extends Comparable> list, T key)二分查找,列表必须已按自然顺序升序;找到返回索引,否则返回负的插入点减 1
binarySearch(List<? extends T> list, T key, Comparator<? super T> c)按指定 Comparator 的二分查找
min(Collection<? extends T> coll)按自然顺序取最小元素
max(Collection<? extends T> coll)按自然顺序取最大元素
min/max(Collection, Comparator)按指定 Comparator 取最小/最大
java
List<Integer> nums = new ArrayList<>(List.of(10, 20, 30, 40, 50));

// 二分查找:列表必须已升序
int index = Collections.binarySearch(nums, 30);  // 2
int notFound = Collections.binarySearch(nums, 25);  // 负数,表示插入点

// 极值
int min = Collections.min(nums);  // 10
int max = Collections.max(nums);  // 50

注意

binarySearch 的前提是列表已按对应顺序排好。若未排序,结果未定义。先 Collections.sort(list)binarySearch


不可变与空集合

空集合

避免返回 null,用空集合表示「无元素」更安全:

方法返回类型说明
emptyList()List<T>不可变的空 List
emptySet()Set<T>不可变的空 Set
emptyMap()Map<K,V>不可变的空 Map
java
// 方法无结果时返回空集合,调用方无需判 null
public List<String> findNames(String filter) {
    if (filter == null || filter.isBlank())
        return Collections.emptyList();
    // ...
    return result;
}

// 调用方可以安全地遍历
for (String name : findNames("")) {
    // 不会进入,也不会 NPE
}

单元素集合

方法说明
singletonList(T o)只含一个元素的不可变 List
singleton(T o)只含一个元素的不可变 Set
singletonMap(K key, V value)只含一个键值对的不可变 Map
java
// 不可变单元素集合,常用于「仅允许一个值」的 API
Set<String> one = Collections.singleton("only");
List<Integer> single = Collections.singletonList(42);
Map<String, Integer> oneEntry = Collections.singletonMap("count", 1);

不可变视图(unmodifiable*)

用现有集合包装成「只读」视图,修改原集合仍会反映到视图中,但对视图的写操作会抛出 UnsupportedOperationException

方法说明
unmodifiableList(List list)不可变 List 视图
unmodifiableSet(Set set)不可变 Set 视图
unmodifiableMap(Map map)不可变 Map 视图
java
List<String> mutable = new ArrayList<>(List.of("A", "B"));
List<String> readOnly = Collections.unmodifiableList(mutable);

readOnly.get(0);        // "A" — 读可以
readOnly.add("C");      // 抛出 UnsupportedOperationException

mutable.add("C");      // 可以,且 readOnly 看到 [A, B, C]

提示

若需要「完全不可变且与原集合无关」的副本,可先复制再包装:Collections.unmodifiableList(new ArrayList<>(original))。Java 9+ 也可使用 List.of()Set.of()Map.of() 等直接创建不可变集合。


同步包装(线程安全视图)

若要在多线程下对 List/Set/Map 做同步访问,可用 synchronized* 包装。每次读写都会在包装对象上加锁,保证线程安全但不是高性能方案:

方法说明
synchronizedList(List list)线程安全的 List 视图
synchronizedSet(Set set)线程安全的 Set 视图
synchronizedMap(Map map)线程安全的 Map 视图
java
List<String> list = new ArrayList<>();
List<String> syncList = Collections.synchronizedList(list);

// 多线程下遍历时,必须对 syncList 做同步,否则可能 ConcurrentModificationException
synchronized (syncList) {
    for (String s : syncList) {
        // 使用 s
    }
}

注意

遍历同步包装的集合时,必须synchronized (syncList) 块内进行,否则迭代器与修改可能并发导致异常。高并发场景更推荐 ConcurrentHashMap 等并发集合。


其他常用方法

方法说明
fill(List list, T obj)将列表中每个位置替换obj
replaceAll(List list, T oldVal, T newVal)将列表中所有等于 oldVal 的元素替换为 newVal
swap(List list, int i, int j)交换索引 ij 的元素
rotate(List list, int distance)整体「旋转」:正数右移,负数左移
frequency(Collection c, Object o)元素 o 在集合中的出现次数
disjoint(Collection c1, Collection c2)两集合是否无交集(无公共元素返回 true
addAll(Collection c, T... elements)将多个元素一次性加入集合
java
List<String> list = new ArrayList<>(List.of("a", "b", "a", "c"));

Collections.replaceAll(list, "a", "A");
// list: [A, b, A, c]

int count = Collections.frequency(list, "A");  // 2

List<String> other = List.of("x", "y");
boolean noCommon = Collections.disjoint(list, other);  // true

List<String> target = new ArrayList<>();
Collections.addAll(target, "one", "two", "three");
// target: [one, two, three]

完整示例:排序与不可变返回

下面示例结合排序不可变视图,实现一个「返回排序后只读列表」的用法:

java
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class CollectionsDemo {

    public static List<String> sortedNamesReadOnly(List<String> names) {
        if (names == null || names.isEmpty())
            return Collections.emptyList();
        List<String> copy = new ArrayList<>(names);
        Collections.sort(copy);
        return Collections.unmodifiableList(copy);
    }

    public static void main(String[] args) {
        List<String> raw = new ArrayList<>(List.of("张三", "李四", "王五"));
        List<String> sorted = sortedNamesReadOnly(raw);

        System.out.println(sorted);   // [李四, 王五, 张三](按自然顺序)
        // sorted.add("赵六");        // 会抛出 UnsupportedOperationException
    }
}

注意事项

  • binarySearch 前必须保证列表已按对应顺序(自然顺序或 Comparator)排好序。
  • unmodifiable* 是视图,底层集合被修改时视图内容会变;若要完全独立不可变,先复制再包装。
  • synchronized* 遍历时需在 synchronized (包装对象) 内进行,高并发更推荐专用并发集合。
  • 返回「无元素」时优先用 emptyList()/emptySet()/emptyMap(),避免返回 null 造成 NPE。

提示

Java 9+ 的 List.of()Set.of()Map.of() 可直接创建不可变集合,无需先可变再包装;但 Collectionsempty*singleton*unmodifiable* 在兼容老版本和接收已有集合做视图时仍然常用。


相关链接

基于 VitePress 构建