Java中根据对象属性对Map<String, Foo>进行排序
根据对象属性对Java Map排序的解决方案
嘿,我来帮你搞定这个Map排序的问题!先给你理清楚核心逻辑:Java里的HashMap本身是无序的,所以咱们得把它的键值对转成可排序的集合,再根据Foo的属性(比如timestamp或者name)来排序,最后如果需要长期保持顺序的话,存到LinkedHashMap这类有序Map里就行。
先给你修正一下代码里的几个小细节,不然编译跑不起来:
- main方法的正确写法是
public static void main(String[] args),你漏了返回值和参数 - 循环变量
int i需要初始化,比如int i = 0; String key = i;要转成字符串类型,改成String key = String.valueOf(i);map.put(key,Foo);这里应该用实例对象foo,不是类名Foo
接下来给你两种常用的实现方式:
方式一:传统Collections.sort写法(兼容Java 8之前)
先把Map的键值对转成List,再用自定义Comparator来排序:
public class Foo{ public long timestamp; public String name; public Foo(long timestamp,String name){ this.timestamp = timestamp; this.name = name; } } public class Main { public static void main(String[] args) { Map<String,Foo> map = new HashMap<>(0); for(int i = 0; i<1000;i++){ // 假设这里的datetime是你生成的时间戳,name是对应字符串 long datetime = System.currentTimeMillis() + i; String name = "foo_" + i; Foo foo = new Foo(datetime,name); String key = String.valueOf(i); map.put(key, foo); } // 把Map的entry转成List List<Map.Entry<String, Foo>> entryList = new ArrayList<>(map.entrySet()); // 按timestamp升序排序 Collections.sort(entryList, new Comparator<Map.Entry<String, Foo>>() { @Override public int compare(Map.Entry<String, Foo> o1, Map.Entry<String, Foo> o2) { // 用Long.compare避免直接相减导致的数值溢出 return Long.compare(o1.getValue().timestamp, o2.getValue().timestamp); } }); // 如果要按timestamp降序,只需要调换两个参数的顺序 Collections.sort(entryList, new Comparator<Map.Entry<String, Foo>>() { @Override public int compare(Map.Entry<String, Foo> o1, Map.Entry<String, Foo> o2) { return Long.compare(o2.getValue().timestamp, o1.getValue().timestamp); } }); // 如果要按name字符串排序 Collections.sort(entryList, new Comparator<Map.Entry<String, Foo>>() { @Override public int compare(Map.Entry<String, Foo> o1, Map.Entry<String, Foo> o2) { return o1.getValue().name.compareTo(o2.getValue().name); } }); } }
方式二:Java 8+流式写法(更简洁)
利用Stream API和Lambda表达式,代码更紧凑:
public class Foo{ public long timestamp; public String name; public Foo(long timestamp,String name){ this.timestamp = timestamp; this.name = name; } } public class Main { public static void main(String[] args) { Map<String,Foo> map = new HashMap<>(0); for(int i = 0; i<1000;i++){ long datetime = System.currentTimeMillis() + i; String name = "foo_" + i; Foo foo = new Foo(datetime,name); String key = String.valueOf(i); map.put(key, foo); } // 按timestamp升序排序,得到有序的entry列表 List<Map.Entry<String, Foo>> sortedByTimestampAsc = map.entrySet() .stream() .sorted(Comparator.comparingLong(entry -> entry.getValue().timestamp)) .collect(Collectors.toList()); // 按timestamp降序排序,加个reversed()就行 List<Map.Entry<String, Foo>> sortedByTimestampDesc = map.entrySet() .stream() .sorted(Comparator.comparingLong(entry -> entry.getValue().timestamp).reversed()) .collect(Collectors.toList()); // 按name字符串排序 List<Map.Entry<String, Foo>> sortedByName = map.entrySet() .stream() .sorted(Comparator.comparing(entry -> entry.getValue().name)) .collect(Collectors.toList()); // 如果需要生成一个保持顺序的Map(比如LinkedHashMap) Map<String, Foo> sortedMap = map.entrySet() .stream() .sorted(Comparator.comparingLong(e -> e.getValue().timestamp)) .collect(Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue, (oldVal, newVal) -> oldVal, // 处理键冲突,保留旧值 LinkedHashMap::new // 指定有序的Map实现 )); } }
额外注意点
- 如果
name属性可能为null,排序时要处理空指针,可以用Comparator.nullsFirst()或nullsLast():.sorted(Comparator.comparing(entry -> entry.getValue().name, Comparator.nullsFirst(String::compareTo))) HashMap本身不维护顺序,所以如果需要长期保存排序后的结果,一定要用LinkedHashMap这类有序Map来存储。
内容的提问来源于stack exchange,提问作者BBR
相关产品推荐
相关产品推荐

