Collections工具类仅提供辅助操作,不支持增删改查;误作集合实现会抛UnsupportedOperationException。

Java 的 Collections 工具类本身不提供“增删改查”能力,它只负责对已存在的 Collection 实例做辅助操作——比如排序、查找、同步包装、不可变视图等。误把它当集合实现来用,会直接抛 UnsupportedOperationException。
为什么调用 sort() 或 binarySearch() 前必须确保 List 可修改且已排序?
这两个方法都要求传入的 List 是可修改的(如 ArrayList),且 binarySearch() 还要求列表已按自然顺序或指定 Comparator 排好序。否则结果不可预测,甚至返回负数却不是插入点。
-
Collections.sort(list)会原地排序,但若list是Collections.unmodifiableList(...)或Arrays.asList()返回的固定大小列表(底层是 final 数组),运行时抛UnsupportedOperationException -
Collections.binarySearch(list, key)不检查是否已排序,只按二分逻辑读取索引 —— 若乱序,返回值既不是匹配位置,也不保证是插入点 - 升序排序后想降序查?得统一用
Comparator.reverseOrder():Collections.sort(list, Comparator.reverseOrder()); int pos = Collections.binarySearch(list, key, Comparator.reverseOrder());
synchronizedXxx() 包装器真的线程安全吗?
它们只是给每个方法加了 synchronized(this),仅能防止多个线程同时调用同一个方法,但无法解决复合操作的竞态问题。
- 例如
if (!list.contains(e)) list.add(e);即使用Collections.synchronizedList(...)包装,仍可能在contains()和add()之间被其他线程插入相同元素 - 迭代时必须手动同步整个块:
synchronized (syncList) { Iteratorit = syncList.iterator(); while (it.hasNext()) { process(it.next()); } } - 现代代码更推荐用
java.util.concurrent类(如CopyOnWriteArrayList、ConcurrentHashMap),而非Collections.synchronizedXxx()
用 unmodifiableXxx() 后,底层集合改了怎么办?
这些方法返回的是“视图”,不拷贝数据。如果原始集合后续被修改,不可变视图会立刻反映变化 —— 但调用其修改方法(如 add())仍会抛 UnsupportedOperationException。
立即学习“Java免费学习笔记(深入)”;
- 典型陷阱:
List
original = new ArrayList<>(); List unmod = Collections.unmodifiableList(original); original.add("hello"); // ✅ 允许 System.out.println(unmod.size()); // 输出 1 —— 视图实时同步 unmod.add("world"); // ❌ 抛 UnsupportedOperationException - 真要彻底隔离,得深拷贝:用构造器(
new ArrayList(original))或Stream.toList()(Java 16+)再套不可变包装 -
Collections.emptyXxx()和Collections.singletonXxx()返回的是单例实例,轻量且线程安全,优先用于空/单元素场景
最常被忽略的一点:所有 Collections 静态方法都不处理 null 元素的语义差异。比如 max() 在含 null 的列表里直接抛 NullPointerException;而 frequency() 能正确统计 null 出现次数 —— 是否支持 null 得挨个看 Javadoc,不能凭经验推断。










