treeset不能直接按字符串长度排序,需自定义comparator;长度相等时不可返回0,否则视为重复元素被丢弃,应转为字典序比较以确保唯一性。

TreeSet 本身不支持直接按字符串长度排序,必须通过传入自定义 Comparator 实现;关键在于比较逻辑要严格满足“可比性”和“一致性”,同时对长度相等的字符串不能返回 0(否则会被视为重复元素而丢弃)。
为什么不能直接用长度相等就返回 0?
TreeSet 底层基于 TreeMap,依赖 Comparator 的返回值判断元素是否重复:若 compare(a, b) == 0,TreeSet 认为 a 和 b 相等,只保留一个。所以即使两个字符串长度相同(如 "hi" 和 "ok"),也不能返回 0,否则后者会被忽略。
正确写法:先比长度,长度相等时再按字典序区分
在 Comparator 中分两步比较:
- 先比较字符串长度,长度小的排前面
- 长度相等时,调用
String.compareTo()进行字典序比较,确保返回非零值
示例代码:
TreeSet<string> set = new TreeSet((s1, s2) -> {
int lenDiff = Integer.compare(s1.length(), s2.length());
if (lenDiff != 0) return lenDiff;
return s1.compareTo(s2); // 长度相同时字典序升序
});
set.addAll(Arrays.asList("a", "bb", "cc", "ddd", "ee", "f"));
// 结果:[a, f, bb, cc, ee, ddd]
</string>
如果想保持插入顺序中同长元素的相对位置?
TreeSet 是有序集合,不维护插入顺序。若需“同长度内按插入先后排列”,它无法原生支持——因为 Comparator 无法获取插入时间。此时应改用其他结构,例如:
- 用
List<string></string>+ 手动排序(Collections.sort(list, comparator)),排序后不自动去重 - 用
LinkedHashSet配合外部排序逻辑,或自定义容器封装
TreeSet 的核心定位是“自动去重 + 有序”,不是“稳定排序容器”。
注意 null 安全和空字符串处理
如果集合中可能含 null 或空字符串,Comparator 需显式处理,否则抛 NullPointerException:
TreeSet<string> set = new TreeSet((s1, s2) -> {
if (s1 == null && s2 == null) return 0;
if (s1 == null) return -1;
if (s2 == null) return 1;
int lenDiff = Integer.compare(s1.length(), s2.length());
if (lenDiff != 0) return lenDiff;
return s1.compareTo(s2);
});
</string>
空字符串 "" 长度为 0,会自然排在最前(只要没 null 干扰)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











