1

当我需要根据值对 Map 进行排序时,我经常会遇到这种情况。地图在 JDK 中并不适用,我决定不使用 Guava(似乎这个东西是一个班轮,但我不太明白)也不是 Apache Commons,所以我这样做了。顺便说一句,是一个非常受欢迎的问题,但大多数答案在某种程度上都是错误的。

    Map<String, Long> map = new HashMap<String, Long>();
    // populate
    List<Map.Entry<String, Long>> list = new LinkedList<Map.Entry<String,Long>>();
    for (Map.Entry<String, Long> entry : map.entrySet()) {
        list.add(entry);
    }
    Collections.sort(list, new MapComparable());
    LinkedHashMap<String, Long> linkedMap = new LinkedHashMap<String, Long>();

    for (Map.Entry<String, Long> entry : list) {
        linkedMap.put(entry.getKey(), entry.getValue());
    }
}

    public static class MapComparable implements Comparator<Map.Entry<String, Long>>{

        public int compare(Entry<String, Long> e1, Entry<String, Long> e2) {
            return (e1.getValue()<e2.getValue() ? -1 : (e1.getValue()==e2.getValue() ? 0 : 1));
        }
    }

我的问题是,有没有更好的方法将 EntrySet 与 Collection 联系起来?看起来不太好。

这可靠吗?

4

2 回答 2

2

您可以维护一个双重数据结构,一个设置为Map提供字符串 -> 长转换的 a,另一个设置为List提供有序转换的或类似的结构,并具有将两者维护在一起的整体结构。

于 2011-06-03T22:19:50.800 回答
2

我认为对您的方法的一个非常轻微的改进是:

Queue queue = new PriorityQueue( map.size(), new MapComparable() );

queue.addAll( map.entrySet() );

LinkedHashMap<String, Long> linkedMap = new LinkedHashMap<String, Long>();

for (Map.Entry<String, Long> entry; (entry = queue.poll())!=null;) {
    linkedMap.put(entry.getKey(), entry.getValue());
}

换句话说,使用为排序而设计的数据结构进行排序。

作为一般说明,代码如

for (Map.Entry<String, Long> entry : map.entrySet()) {
    list.add(entry);
}

可以缩短为:

list.addAll( map.entrySet() );

每当您与Collections 打交道时。

我也认为:

public int compare(Entry<String, Long> e1, Entry<String, Long> e2) {
    return e1.getValue().compareTo(e2.getValue());
}

更干净。

于 2011-06-04T08:46:59.790 回答