含下划线字符串的降序排序结果不符问题排查
排序异常问题排查与修复
核心问题
你代码里犯了两个关键错误:
- 两次排序调用覆盖了结果:你先通过自定义Comparator排序,但紧接着又调用
Collections.sort(sortedcolumnList, Collections.reverseOrder(String.CASE_INSENSITIVE_ORDER)),这直接把之前的自定义排序结果冲掉了,最终生效的是大小写不敏感的逆序排序,完全没用到你写的分组规则。 - 自定义Comparator逻辑错误:递归调用
compare(o1.substring(1), o2.substring(1))会不断截取字符串首字符,直到没有下划线,这完全不是你需要的「含下划线的字符串优先」的分组逻辑,反而会打乱字符串的自然排序。
需求匹配与修正方案
从你的预期结果来看,需求是:
- 含下划线的字符串排在所有不含下划线的字符串前面
- 同组内(都含/都不含下划线)按大小写不敏感的降序排序
修正后的代码(用Java 8+的链式Comparator更简洁清晰):
protected void validateDescendingOrder(Integer column) { // 获取目标列数据 List<String> columnList = getColumnList(column); // 复制列表用于排序 List<String> sortedColumnList = new ArrayList<>(columnList); // 自定义排序规则 sortedColumnList.sort(Comparator.comparing((String s) -> !s.contains("_")) // 第一步:含下划线的在前(!s.contains("_")返回false,升序时false排在true前) .thenComparing(String::compareToIgnoreCase, Comparator.reverseOrder())); // 第二步:同组内按大小写不敏感降序排序 // 打印对比 System.out.println(sortedColumnList); System.out.println(columnList); // 校验顺序是否匹配 assertEquals(sortedColumnList, columnList); }
原错误逻辑的影响
你第二次调用的Collections.reverseOrder(String.CASE_INSENSITIVE_ORDER)是按字符串的ASCII值做大小写不敏感的逆序排序。由于下划线(ASCII 95)的码值比大写字母R(ASCII 82)大,所以Test_jenn在大小写不敏感的自然排序中会比TestRelease大,逆序后TestRelease就会排在前面,这就是你实际得到错误结果的原因。
内容的提问来源于stack exchange,提问作者kc29
相关产品推荐
相关产品推荐

