java - 如何对 map 列表进行二次排序

标签 java sorting secondary-sort

假设我有以下 map 列表

[{id:1,count:2,name:xyz},
 {id:2,count:3,name:def},
 {id:3,count:2,name:abc},
 {id:4,count:5,name:ghj}
]

我首先想按计数然后按名称对这张 map 进行排序:

期望的输出:

[{id:3,count:2,name:abc},
 {id:1,count:2,name:xyz},
 {id:2,count:3,name:def},
 {id:4,count:5,name:ghj}
]

我尝试了以下进行第一次排序,但在按计数排序后无法使用名称进行排序

Collections.sort(list, new Comparator() {
      public int compare(Object o1, Object o2) {
           return ((Comparable) ((Map.Entry) (o1)).getValue())
          .compareTo(((Map.Entry) (o2)).getValue());
      }

最佳答案

在 Java 1.8 中,我会使用新的 Comparator 方法(尽管缺少类型推断使得必须声明所有类型,从而降低易感性):

    final Comparator<Map<String, Comparable<Object>>> nameThenCountComparator = Comparator.<Map<String, Comparable<Object>>, Comparable<Object>> comparing(
            m -> m.get("name")).thenComparing(Comparator.<Map<String, Comparable<Object>>, Comparable<Object>> comparing(
            m -> m.get("count")));

对于 Java 1.7,我可能会使用 chainedComparator(参见 Apache 的 ComparatorUtils 或 Guava 的 Ordering)和自定义 MapValueComparator(公共(public)库中可能有一个,但尚未找到)。然后想要的顺序变得非常可读:

    class MapValueComparator implements Comparator<Map<String, Object>> {
        private final String key;

        public MapValueComparator(final String key) {
            this.key = key;
        }

        @Override
        public int compare(final Map<String, Object> o1, final Map<String, Object> o2) {
            return ((Comparable<Object>)o1.get(key)).compareTo(o2.get(key));
        }
    }

    Comparator<Object> nameThenCountComparator = ComparatorUtils.chainedComparator(
            new MapValueComparator("name"), 
            new MapValueComparator("count")
    );

然后使用它(Java 7 或 8):

final List<Map<String, Comparable<Object>>> list = null;
Collections.sort(list, nameThenCountComparator);

Rq:如其他答案所述,您应该检查 MapValueComparator 中的空值和缺失键。

关于java - 如何对 map 列表进行二次排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32472775/

相关文章:

Java 检查枚举值是否是返回的一组其他枚举值的一部分

java - java内部在什么地方运行异常

java - 使用非总排序标准对 java 流进行排序。

vba - 按默认属性对一组类进行排序

Java/Android - 两个 Collections.sort 组合(首先按 int,然后按名称)

java 二维数组二次​​排序

带有抽象类的 java.lang.InstantiationException 使用组件扫描

java - Oracle Java 代码约定