
本文旨在解决java `treemap`对字符串类型键进行非标准排序的问题,特别是当字符串代表数字时,如何实现按数值大小进行降序排列。我们将详细介绍如何通过为 `treemap` 提供自定义 `comparator` 来覆盖其默认的字典序排序行为,从而实现将字符串键解析为长整型并进行数值比较,最终达到预期的降序排列效果。
TreeMap 是 Java 集合框架中一个基于红黑树实现的 Map 接口,它能够保持键的有序性。默认情况下,TreeMap 会根据键的自然顺序(如果键实现了 Comparable 接口)进行排序,或者根据在构造 TreeMap 时提供的 Comparator 进行排序。对于 String 类型的键,其自然顺序是字典序(lexicographical order)。
这意味着,当 String 键被 TreeMap 存储时,它们会按照字符的 Unicode 值进行逐位比较。例如,"5903766131" 会被认为小于 "59037662",因为在第三位字符 '0' 和 '3' 的比较中,'0' 小于 '3'。这与我们期望的数值大小排序(即 "59037662" 小于 "5903766131")是相悖的。
考虑以下示例代码,它展示了 TreeMap 默认的字符串键排序行为:
import java.util.Map;
import java.util.TreeMap;
public class ApplicationMain {
public static void main(String[] args) {
final Map<String, Integer> sampleTreeMap = new TreeMap<>();
sampleTreeMap.put("5903766131", 6);
sampleTreeMap.put("5903767", 7);
sampleTreeMap.put("590376614", 5);
sampleTreeMap.put("5903766170", 9);
sampleTreeMap.put("59037662", 12);
sampleTreeMap.put("5903766410", 10);
System.out.println("--- TreeMap 默认排序结果 ---");
sampleTreeMap.entrySet().stream().forEach(entry -> {
System.out.println("Key : " + entry.getKey() + " -- Value : " + entry.getValue());
});
}
}上述代码的输出将是:
立即学习“Java免费学习笔记(深入)”;
--- TreeMap 默认排序结果 --- Key : 5903766131 -- Value : 6 Key : 590376614 -- Value : 5 Key : 5903766170 -- Value : 9 Key : 59037662 -- Value : 12 Key : 5903766410 -- Value : 10 Key : 5903767 -- Value : 7
可以看到,"5903766131" 排在了 "59037662" 之前,这显然不是按数值大小排序的结果。
为了实现将 String 类型的键按照其代表的数值大小进行降序排列,我们需要在 TreeMap 构造时提供一个自定义的 Comparator。这个 Comparator 的核心逻辑是将 String 键解析为数值类型(例如 Long),然后基于这些数值进行比较。
以下是实现这一目标的修改方案:
import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;
public class ApplicationMain {
public static void main(String[] args) {
// 创建 TreeMap 时提供自定义 Comparator
// Comparator.comparingLong 将 String 转换为 Long 进行比较
// .reversed() 将默认的升序比较结果反转为降序
final Map<String, Integer> sampleTreeMap =
new TreeMap<>(Comparator.comparingLong((String s) -> Long.parseLong(s)).reversed());
sampleTreeMap.put("5903766131", 6);
sampleTreeMap.put("5903767", 7);
sampleTreeMap.put("590376614", 5);
sampleTreeMap.put("5903766170", 9);
sampleTreeMap.put("59037662", 12);
sampleTreeMap.put("5903766410", 10);
System.out.println("\n--- TreeMap 自定义数值降序排序结果 ---");
sampleTreeMap.entrySet().stream().forEach(entry -> {
System.out.println("Key : " + entry.getKey() + " -- Value : " + entry.getValue());
});
}
}修改后的代码将产生以下输出:
--- TreeMap 自定义数值降序排序结果 --- Key : 5903766410 -- Value : 10 Key : 5903766170 -- Value : 9 Key : 5903766131 -- Value : 6 Key : 590376614 -- Value : 5 Key : 59037662 -- Value : 12 Key : 5903767 -- Value : 7
可以看到,键已按照其数值大小进行了降序排列,这正是我们期望的结果。
让我们深入理解 new TreeMap<>(Comparator.comparingLong((String s) -> Long.parseLong(s)).reversed()); 这行代码:
因此,这个组合 Comparator 首先将 String 键转换为 long 类型进行数值比较,然后将比较结果反转,使得较大的数值排在前面。
TreeMap 是一个功能强大的有序映射,但其默认的 String 键排序是字典序。当需要对 String 键进行非标准的数值排序时,通过提供自定义 Comparator 是最灵活和推荐的方法。利用 Comparator.comparingLong() 结合 Lambda 表达式进行类型转换,并使用 .reversed() 实现降序,可以优雅地解决此类问题。理解 TreeMap 的工作原理和 Comparator 的灵活运用,是有效利用 Java 集合框架的关键。
以上就是Java TreeMap 字符串键值按数值降序排序指南的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号