理解 java.util.Collections 工具类的作用与定位
掌握常用集合工具方法的使用场景与实现效果
区分 Collection(接口) 与 Collections(工具类) 的本质差异
熟悉常见集合类(如 ArrayList、HashMap、TreeSet 等)的基本特性
能够在实际开发中灵活运用排序、搜索、同步、不可变视图等高级功能
初学者常混淆这两个概念:
记住:Collection 是“容器”,Collections 是“工具箱”
Java 集合框架提供了多种实现类,适用于不同场景:

ArrayList:基于动态数组,支持随机访问,非线程安全
LinkedList:基于双向链表,插入 / 删除快,随机访问慢
Vector:线程安全的动态数组(已不推荐,建议用 Collections.synchronizedList)
HashSet:基于哈希表,无序,查找快(内部使用 HashMap)
LinkedHashSet:维护插入顺序的 HashSet
TreeSet:基于红黑树,元素自动排序(自然序或自定义比较器)
HashMap:键值对存储,非线程安全,允许一个 null 键和多个 null 值
TreeMap:按键排序的 Map,基于红黑树
EnumMap:专为枚举类型设计的高性能 Map
PriorityQueue:优先级队列,按自然序或比较器排序
ArrayDeque:双端队列,支持栈和队列操作,性能优于 Stack
Stack:继承自 Vector,实现 LIFO 栈(官方已不推荐,建议用 ArrayDeque)
Collections 类提供三大类实用方法:
这些方法返回空或单元素的不可变集合,常用于初始化或防御性编程:
List<String> emptyList = Collections.emptyList(); // []
Set<Integer> emptySet = Collections.emptySet(); // {}
Map<String, String> emptyMap = Collections.emptyMap(); // {}
List<String> single = Collections.singletonList("OK"); // ["OK"]
Set<String> singleSet = Collections.singleton("YES"); // {"YES"}
Map<String, Integer> oneEntry = Collections.singletonMap("count", 1);所有返回对象均为 不可修改,调用
add()或put()会抛出UnsupportedOperationException
List<String> list = new ArrayList<>();
Collections.addAll(list, "A", "B", "C"); // 批量添加List<Integer> nums = Arrays.asList(3, 1, 4, 1, 5);
Collections.sort(nums); // [1, 1, 3, 4, 5]
Collections.sort(nums, Collections.reverseOrder()); // [5, 4, 3, 1, 1]必须先排序!
int index = Collections.binarySearch(sortedList, "target");
if (index >= 0) {
System.out.println("Found at: " + index);
} else {
int insertPos = -index - 1; // 应插入位置
}List<String> dest = new ArrayList<>(Arrays.asList("X", "Y", "Z", "W"));
List<String> src = Arrays.asList("A", "B", "C");
Collections.copy(dest, src); // dest becomes ["A", "B", "C", "W"]目标列表长度必须 ≥ 源列表,否则抛出
IndexOutOfBoundsException
int count = Collections.frequency(list, "Apple"); // 统计出现次数
boolean noCommon = Collections.disjoint(list1, list2); // 是否无交集
Collections.reverse(list); // 反转
Collections.shuffle(list); // 随机打乱
Collections.fill(list, "N/A"); // 全部替换为指定值
Collections.swap(list, 0, 1); // 交换两个位置元素线程安全
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
Set<Integer> syncSet = Collections.synchronizedSet(new HashSet<>());
Map<String, Object> syncMap = Collections.synchronizedMap(new HashMap<>());使用时仍需手动同步遍历操作:
synchronized (syncList) { for (String s : syncList) { ... } }
防御性编程
List<String> safeView = Collections.unmodifiableList(originalList);
// 任何修改操作都会抛出异常运行时校验
List<String> checkedList = Collections.checkedList(new ArrayList<>(), String.class);
checkedList.add("OK"); // OK
checkedList.add(123); // 抛出 ClassCastException(即使编译通过)List<String> items = new ArrayList<>();
items.add("Shoes");
Collections.addAll(items, "Fruits", "Bat", "Ball");
// 结果: [Shoes, Fruits, Bat, Ball]Collections.sort(items); // 默认自然序
Collections.sort(items, Collections.reverseOrder()); // 逆序Collections.sort(items);
int pos = Collections.binarySearch(items, "Horse"); // 返回索引 2
int notFound = Collections.binarySearch(items, "Dog"); // 返回 -2(表示应插入位置为 1)List<String> dest = Arrays.asList("Shoes", "Toys", "Horse", "Tiger");
List<String> src = Arrays.asList("Bat", "Frog", "Lion");
Collections.copy(dest, src);
// dest 变为: [Bat, Frog, Lion, Tiger]boolean disjoint = Collections.disjoint(list1, list2); // true 表示无共同元素Collections 类提供三个静态字段,用于获取不可变的空集合实例:
public static final List EMPTY_LIST;
public static final Set EMPTY_SET;
public static final Map EMPTY_MAP;使用方式:
List<String> empty = Collections.EMPTY_LIST; // 不推荐(原始类型)
List<String> empty = Collections.emptyList(); // 推荐(泛型安全)建议始终使用带泛型的方法(如
emptyList()),避免类型转换警告
优先使用不可变集合
当集合内容确定后,用 unmodifiableXXX() 包装,防止意外修改。
谨慎使用同步包装synchronizedXXX() 仅提供基本线程安全,高并发场景建议使用 ConcurrentHashMap、CopyOnWriteArrayList 等并发集合。
排序前务必确认有序性binarySearch() 要求列表已按相同规则排序,否则结果不可预测。
避免直接使用 Vector / Stack
它们是遗留类,性能较差。用 ArrayList + Collections.synchronizedList 或 ArrayDeque 替代。
利用工具方法提升代码简洁性
如 nCopies(5, "X") 生成 [X, X, X, X, X],比手写循环更清晰。
Collections 是 静态工具类,提供对集合的通用操作
核心功能包括:排序、搜索、批量操作、同步包装、不可变视图、类型检查
常见集合类各有适用场景:ArrayList(随机访问)、LinkedList(频繁插入)、HashSet(去重)、TreeSet(排序)等
使用 binarySearch() 前必须确保列表已排序
不可变集合和同步包装是构建健壮、线程安全程序的重要手段
为什么 Collections.synchronizedList(new ArrayList<>()) 在遍历时仍需要外部同步?请结合其内部实现说明。
Collections.unmodifiableList() 返回的是“浅不可变”还是“深不可变”?如果列表中存储的是可变对象(如 Date),会发生什么问题?
假设你需要一个最多缓存 100 个最近使用的字符串的集合,并自动淘汰最旧的元素。你会选择哪种集合类?如何结合 Collections 工具类实现?