Java实现基于输入条件和升降序的自定义排序问题排查
问题分析与解决方案
问题根源
name343排在name36之前的问题,核心原因是String的compareTo方法采用字典序逐字符比较,而非按数字的数值大小比较:
- 对比
"name343"和"name36"时,数字部分的第二个字符'4'的ASCII值小于'6',字典序判定"name343"更小,因此排在前面。但实际需求是按数字的数值排序,所以必须提取字符串中的数字部分,转为数值后再比较。
修正方案
步骤1:编写数字提取工具方法
实现一个方法,从name或id字符串中提取纯数字并转为整数:
private static Integer extractNumber(String str) { // 移除所有非数字字符,提取纯数字字符串 String numStr = str.replaceAll("[^0-9]", ""); // 空字符串返回0,否则转为Integer return numStr.isEmpty() ? 0 : Integer.parseInt(numStr); }
步骤2:修改原有冒泡排序的比较逻辑
将原代码中直接用字符串compareTo的逻辑,替换为基于提取数字的数值比较:
private static void sortBasedonInput(List<List<String>> items, String sortOrder, int sortParameter) { System.out.println("before sort: " + items); // 冒泡排序核心逻辑修改 for (int j = 0; j < items.size(); j++) { for (int i = 0; i < items.size() - 1; i++) { // 提取当前元素和下一个元素的数字值 Integer currentNum = extractNumber(items.get(i).get(sortParameter)); Integer nextNum = extractNumber(items.get(i+1).get(sortParameter)); // 按数值大小比较交换 if (currentNum.compareTo(nextNum) > 0) { List<String> temp = items.get(i); items.set(i, items.get(i+1)); items.set(i+1, temp); } } } if ("asc".equalsIgnoreCase(sortOrder)) { System.out.println(items); } else { Collections.reverse(items); System.out.println(items); } }
优化方案(使用Java内置排序API更简洁高效)
手动实现冒泡排序易出错且效率低,推荐用Collections.sort配合自定义Comparator简化代码:
private static void sortBasedonInput(List<List<String>> items, String sortOrder, int sortParameter) { System.out.println("before sort: " + items); Collections.sort(items, (item1, item2) -> { Integer num1 = extractNumber(item1.get(sortParameter)); Integer num2 = extractNumber(item2.get(sortParameter)); // 根据排序顺序返回比较结果 return sortOrder.equalsIgnoreCase("asc") ? num1.compareTo(num2) : num2.compareTo(num1); }); System.out.println(items); }
验证结果
运行修正后的代码,按name升序排序的输出将变为:
[[name1, id12], [name22, id99], [name36, id5], [name343, id3], [name99, id1]]
完全符合预期的数值排序结果。
内容的提问来源于stack exchange,提问作者PotatoGod
相关产品推荐
相关产品推荐

