繁体   English   中英

如何在地图列表上进行二级排序

[英]How can I do a secondary sorting on a list of maps

让我们假设我有以下地图列表

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

我首先要按计数然后按名称对此地图进行排序:

期望的输出:

[{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());
      }

假设list的类型是List<Map<String,Object>> (不清楚Map的值是什么类型,所以我使用了Object ),你的Comparator应该能够比较两个Map<String,Object>实例。

Collections.sort(list, new Comparator<Map<String,Object>>() {
      public int compare(Map<String,Object> o1, Map<String,Object> o2) {
           // first compare o1.get("count") to o2.get("count")
           // if they are equal, compare o1.get("name") to o2.get("name")
           // don't forget to handle nulls (for example if either o1 or o2 is null
           // or if any of the keys are not present in one or both of the maps)
      }

使用Java 1.8,我会使用新的Comparator方法(尽管缺少Type推理使得必须声明所有类型,从而减少了lisibility):

    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(可能有一个在公共库中,但还没有找到它)。 然后想要的订单变得非常可读:

    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中是否存在空值和缺少键。

如果我理解正确,你有一个List<Map<String, Object>> 您需要编写自定义Comparator才能对其进行排序。 在那里,您可以单独比较每个条目(为了简洁而删除了错误处理):

public class ListMapComparator implements Comparator<List<Map<String, Object>>> {

    @Override
    public in compare (List<Map<String, Object>> l1, List<Map<String, Object>> l2) {
        Integer count1 = (Integer)l1.get("count");
        Integer count2 = (Integer)l2.get("count");
        int comp = count1.compare(count2);
        if (comp != 0) {
            return comp;
        }

        String name1 = (String)l1.get("name");
        String name2 = (String)l2.get("name");
        return name1.compare(name2);
    }    
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM