如何对存储数字的String类型ArrayList进行数值排序?
解决字符串数字列表的数值排序问题
嘿,我完全懂你碰到的这个坑——当你直接用Collections.sort()对存储数字的String列表排序时,它默认会按字典序来排列,这就是为什么会出现1 10 11...2 20...这种和预期数值顺序不符的结果。毕竟字符串比较是逐字符来的,'1'的ASCII码比'2'小,所以"10"会排在"2"前面。
问题根源
你提到尝试转成int[]用Arrays.sort()但没得到正确结果,大概率是操作环节出了问题——比如你可能只是排序了int数组,但没把排序后的数值再转回String列表;或者你的测试代码里,IntStream.rangeClosed(1,30).toArray()生成的本来就是有序的int数组,转成String列表自然是有序的,没体现出排序问题。
两种有效解决方案
方案一:给Collections.sort()传自定义比较器
直接在排序String列表时,指定按数值大小比较的规则,不用来回转换类型:
// 假设你的字符串数字列表是rangeList Collections.sort(rangeList, Comparator.comparingInt(Integer::parseInt));
或者用Lambda表达式写得更直观:
Collections.sort(rangeList, (str1, str2) -> { int num1 = Integer.parseInt(str1); int num2 = Integer.parseInt(str2); return Integer.compare(num1, num2); });
方案二:转成Integer列表排序后再转回String
如果更习惯先处理数值类型,也可以先把String列表转成Integer列表排序,再转回来:
import java.util.stream.Collectors; // 转为Integer列表排序 List<Integer> sortedIntList = rangeList.stream() .map(Integer::parseInt) .sorted() .collect(Collectors.toList()); // 转回String类型的ArrayList List<String> sortedStringList = sortedIntList.stream() .map(String::valueOf) .collect(Collectors.toCollection(ArrayList::new));
完整测试示例
比如模拟一个打乱顺序的字符串数字列表,验证排序效果:
import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.stream.Collectors; public class NumberSortTest { public static void main(String[] args) { // 模拟乱序的字符串数字列表 List<String> unsortedList = new ArrayList<>(Arrays.asList("10", "2", "1", "25", "3")); // 方案一测试 Collections.sort(unsortedList, Comparator.comparingInt(Integer::parseInt)); System.out.println("方案一排序结果:" + unsortedList); // 输出 [1, 2, 3, 10, 25] // 重新生成乱序列表测试方案二 unsortedList = new ArrayList<>(Arrays.asList("10", "2", "1", "25", "3")); List<String> sortedList = unsortedList.stream() .map(Integer::parseInt) .sorted() .map(String::valueOf) .collect(Collectors.toCollection(ArrayList::new)); System.out.println("方案二排序结果:" + sortedList); // 同样输出正确顺序 } }
内容的提问来源于stack exchange,提问作者user3745394
相关产品推荐
相关产品推荐

