Как улучшить сортировку значений Карты через Коллекции - PullRequest
1 голос
/ 04 июня 2011

Я часто попадаю в ситуацию, когда мне нужно отсортировать карту по значениям. Карты не предназначены для этого в 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? Это не выглядит хорошо.

И это надежно?

Ответы [ 2 ]

2 голосов
/ 04 июня 2011

То, что я считаю очень незначительным улучшением вашего метода:

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() );

всякий раз, когда вы имеете дело с Collection с.

Также я думаю, что это:

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

чище.

2 голосов
/ 04 июня 2011

Вы можете поддерживать двойную структуру данных, одну из которых задайте как Map, которая обеспечивает строковые -> длинные преобразования, а другую - как List или аналогичную структуру, которая обеспечивает упорядоченные преобразования, с общей структурой, которая поддерживает оба вместе .

...