Collections.sort()需传Comparator(如lambda或方法引用);unmodifiableXXX返回不可变视图而非深拷贝;synchronizedXXX仅保证单操作原子性,复合操作仍需手动同步;singletonXXX返回共享单例,非独立集合。

如何用 Collections.sort() 对自定义对象排序
直接调用 Collections.sort() 会抛 ClassCastException,除非你的类实现了 Comparable 接口。更常见也更灵活的做法是传入 Comparator 实现:
- 用 lambda 表达式最简洁:
Collections.sort(list, (a, b) -> Integer.compare(a.getAge(), b.getAge())); - Java 8+ 推荐用方法引用:
Collections.sort(list, Comparator.comparing(Person::getAge)); - 注意:
sort()只支持List,对Set或Map的 value 需先转成List - 如果 list 里有
null,默认比较器会抛NullPointerException;可用Comparator.nullsLast(Comparator.comparing(...))处理
Collections.unmodifiableXXX() 真的安全吗
它返回的是“不可变视图”,不是深拷贝。原集合一旦被修改,视图可能抛 ConcurrentModificationException,也可能读到脏数据。
-
Collections.unmodifiableList(list)返回的 list 调用add()会立即抛UnsupportedOperationException - 但若原
list是可变的(比如new ArrayList()),外部仍能通过原始引用修改它,视图同步可见 - 真正防篡改需配合防御性拷贝:
new ArrayList(originalList)再套一层unmodifiableList - 注意:
unmodifiableMap的 key 和 value 本身不被保护,只是 map 结构不可变
为什么 Collections.synchronizedXXX() 在高并发下仍可能出错
它只保证单个操作原子,不保证复合操作线程安全。比如 if (!list.isEmpty()) list.remove(0); 这种判断+操作,在多线程下依然存在竞态。
-
Collections.synchronizedList(list)包裹后,get()、set()单独调用是线程安全的 - 但迭代必须手动同步:
synchronized (list) { for (e : list) { ... } },否则可能抛ConcurrentModificationException - 替代方案更推荐
CopyOnWriteArrayList(读多写少)或ConcurrentHashMap(高并发 Map 场景) - 这些包装类没有解决迭代期间结构变更的问题,本质是“伪线程安全”
Collections.singletonXXX() 的典型误用场景
这类方法(如 Collections.singletonList()、Collections.singletonMap())返回的是轻量级不可变单元素集合,适合做返回值或参数占位,但别把它当普通容器反复复用。
立即学习“Java免费学习笔记(深入)”;
- 它们是单例实现,多次调用返回同一对象(JVM 级别共享),所以不能用来存不同值
-
Collections.singletonList("a") == Collections.singletonList("a")可能为true(取决于 JVM 实现和是否启用常量池优化) - 如果需要多个独立的单元素 list,必须每次 new:
Arrays.asList("a")或new ArrayList(Arrays.asList("a")) - 注意:
singletonList返回的 list 不支持set()(抛UnsupportedOperationException),哪怕设回原值也不行










