descendingset() 返回原 treeset 的动态逆序视图,非副本,所有修改实时双向同步;遍历时仅迭代器 remove() 安全;不支持 clone/序列化;需独立副本须显式构造;自定义 comparator 自动反向,null 处理存在兼容性风险。

descendingSet() 返回的不是副本,而是原 TreeSet 的动态逆序视图,所有修改操作都会实时双向同步。
增删改操作完全联动
对 descendingSet() 执行 add、remove、clear 等操作,等价于直接操作原 TreeSet:
- add(x):x 会出现在原 set 中,且在 descendingSet() 视图里排在最前(因是降序)
- remove(x):x 从原 set 和 descendingSet() 中同时消失
- clear():原 set 变为空,descendingSet() 也立即为空
遍历中修改会触发 ConcurrentModificationException
这是关键限制:若正在用 descendingSet().iterator() 遍历时,通过原 set 或其他方式修改结构(如 add/remove),迭代器会立刻抛出 ConcurrentModificationException。
唯一安全的修改方式是使用该迭代器自身的 remove() 方法——它能同步更新原 set 并维持迭代一致性。
视图不可独立存在
descendingSet() 不支持 clone(),也不能序列化;它没有自己的底层存储,完全依赖原 TreeSet 的红黑树结构。
若需要真正独立的逆序副本,必须显式构造:
- new TreeSet(original.descendingSet()) —— 利用其元素构造新 TreeSet
- new TreeSet(Collections.reverseOrder()).addAll(original) —— 更明确地指定降序逻辑
比较器与 null 的特殊行为
原 TreeSet 若使用自定义 Comparator,descendingSet() 会自动采用其反向版本(Collections.reverseOrder(comparator));但 null 元素处理较脆弱:
- 即使原 set 允许 null(如用
Comparator.nullsFirst构造),descendingSet() 在某些 JDK 版本中仍可能抛 NullPointerException - null 在原 set 中排最前,在 descendingSet() 中就排最后;但该位置翻转逻辑未必被所有实现完整支持
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











