java中如何使用TreeMap进行键值对排序

本文通过定义 Java 实体类 Person,并使用 TreeMap 进行实例化与排序操作,展示了 TreeMap 的升序排序特性及其在键值对存储中的应用。通过代码示例,详细解释了如何将 Person 对象作为键值对存入 TreeMap 中,并遍历输出排序后的键值对,最终呈现出有序的人名列表。

TreeMap是可以保存键值对的一种方式,它的特殊之处是它可以自动以键进行升序排序。

下面举例说明它的用法。

首先定义一个实体类Person,有name和age属性:

[java]  view plain copy print ?
  1. public class Person {  
  2.     private String name;  
  3.     private int age;  
  4.   
  5.     public Person(String name, int age) {  
  6.         this.name = name;  
  7.         this.age = age;  
  8.     }  
  9.   
  10.     public String getName() {  
  11.         return this.name;  
  12.     }  
  13.   
  14.     public int getAge() {  
  15.         return this.age;  
  16.     }  
  17. }  

举例使用TreeMap的test类:

[java]  view plain copy print ?
  1. import java.util.Iterator;  
  2. import java.util.Map.Entry;  
  3. import java.util.Set;  
  4. import java.util.TreeMap;  
  5.   
  6. public class test {  
  7.   
  8.     public static void main(String[] args) {  
  9.         TreeMap<Long, Object> treeMap = new TreeMap<Long, Object>();  
  10.         treeMap.put((long1new Person("Json"20));  
  11.         treeMap.put((long8new Person("Peter"22));  
  12.         treeMap.put((long9new Person("Divid"25));  
  13.         treeMap.put((long6new Person("Aglia"22));  
  14.         // Get a set of entries  
  15.         Set<Entry<Long, Object>> set = treeMap.entrySet();  
  16.         // Get an iterator  
  17.         Iterator<Entry<Long, Object>> iterator = set.iterator();  
  18.         // Display elements  
  19.         while (iterator.hasNext()) {  
  20.             Entry<?, ?> entry = (Entry<?, ?>) iterator.next();  
  21.             System.out.println(((Person)entry.getValue()).getName());  
  22.         }  
  23.     }  
  24. }  

控制台运行结果:


可以看出打印出来的是经过键升序排序的。这里的键可以是Integer,String等类型,默认按照升序进行排列。



原文链接:

http://blog.youkuaiyun.com/cangkukuaimanle/article/details/6882724

### TreeMap 的基本排序机制 `TreeMap` 是基于红黑树实现的 `NavigableMap`,它能够按照的自然顺序或自定义顺序进行排序。在默认情况下,`TreeMap` 使用的自然顺序进行排序,前提是必须实现 `Comparable` 接口。如果需要自定义排序规则,则可以在构造 `TreeMap` 时传入一个 `Comparator` 实例。 例如,使用 `Comparator.reverseOrder()` 创建一个按降序排列的 `TreeMap`: ```java TreeMap<Integer, String> map = new TreeMap<>(Comparator.reverseOrder()); map.put(3, "val"); map.put(2, "val"); map.put(1, "val"); map.put(5, "val"); map.put(4, "val"); System.out.println(map); // 输出 {5=val, 4=val, 3=val, 2=val, 1=val} ``` 此方式适用于对进行反向排序的需求,也可以通过自定义 `Comparator` 来实现更复杂的排序逻辑[^3]。 --- ### 按排序的实现方法 虽然 `TreeMap` 默认是根据进行排序的,但可以通过一些技巧来实现基于排序。一种常见的做法是创建一个 `LinkedHashMap`,并将其插入顺序保持为根据排序后的结果。具体步骤如下: 1. 将原始 `Map` 的键值对转换为一个 `List`。 2. 使用自定义的比较器对列表进行排序。 3. 将排序后的键值对依次放入 `LinkedHashMap` 中,以保持顺序。 以下是一个示例代码,展示如何实现这一过程: ```java import java.util.*; public class SortMapByValue { public static void main(String[] args) { Map<Integer, String> map = new HashMap<>(); map.put(1, "Apple"); map.put(3, "Orange"); map.put(2, "Banana"); Map<Integer, String> sortedMap = sortByValue(map); System.out.println(sortedMap); // 输出 {1=Apple, 2=Banana, 3=Orange} } public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) { List<Map.Entry<K, V>> list = new ArrayList<>(map.entrySet()); list.sort(Map.Entry.comparingByValue()); Map<K, V> result = new LinkedHashMap<>(); for (Map.Entry<K, V> entry : list) { result.put(entry.getKey(), entry.getValue()); } return result; } } ``` 该方法利用了 `Map.Entry.comparingByValue()` 方法进行排序,并通过 `LinkedHashMap` 保留排序后的插入顺序[^1]。 --- ### 自定义比较器的应用场景 在某些情况下,默认的自然排序可能无法满足需求,此时可以使用自定义比较器。例如,当中包含 `null` 时,标准的自然排序会抛出 `NullPointerException`,而自定义比较器可以灵活处理这种情况。 以下是一个支持 `null` 的自定义比较器示例: ```java TreeMap<String, Integer> withNull = new TreeMap<>((a, b) -> { if (a == null) return b == null ? 0 : -1; if (b == null) return 1; return a.compareTo(b); }); withNull.put(null, 1); ``` 在这个例子中,`null` 被赋予了一个特定的优先级,使得整个排序过程更加灵活和健壮[^2]。 --- ### 内存占用与性能考量 由于 `TreeMap` 是基于红黑树实现的,其每个节点除了存储键值对外,还需要额外的空间来维护树结构(如左右子节点、父节点以及颜色信息)。这导致 `TreeMap` 的内存消耗通常比 `HashMap` 更高,大约高出 30% 左右。相比之下,`HashMap` 使用哈希表结构,内存占用更为紧凑,但在负载因子较低时可能会存在未使用的数组槽位。 因此,在选择数据结构时,应根据具体场景权衡内存占用和操作效率。对于需要频繁排序且数据量较大的情况,`TreeMap` 是一个合适的选择;而对于不需要排序、追求高效查找和插入的场景,则更适合使用 `HashMap`。 --- ### 典型使用场景 - **按排序**:当需要根据的自然顺序或自定义顺序对数据进行排序时,`TreeMap` 是首选方案。例如,统计用户分数排行榜时,可以将用户名作为,分数作为,并按用户名排序。 - **范围查询**:`TreeMap` 提供了丰富的导航方法(如 `floorEntry()`、`ceilingEntry()` 等),非常适合用于执行范围查询和最近匹配操作。 - **分组排序**:结合 `Stream API` 和 `TreeMap`,可以在原排序基础上进一步实现分组排序,适用于多条件排序的复杂业务逻辑。 --- ### 相关问题 1. 如何在 Java使用 TreeMap 进行自定义排序? 2. TreeMap 和 HashMap 在性能和内存占用方面有哪些差异? 3. 如何在 Java 中实现基于 Map 排序? 4. TreeMap 是否支持 null 和 null ?如何处理? 5. TreeMap 提供了哪些导航方法?它们的典型应用场景是什么?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值