Получите minvalue Карты (Ключ, дважды)

Есть ли метод (возможно, с Google Collections) для получения минимального значения a Map(Key, Double)?

Традиционным способом я должен был бы отсортировать карту согласно значениям и взять первое/последнее.

23
задан peterh says reinstate Monica 15 August 2017 в 18:20
поделиться

5 ответов

Для этого вы можете использовать стандартные Коллекции # min () .

Map<String, Double> map = new HashMap<String, Double>();
map.put("1.1", 1.1);
map.put("0.1", 0.1);
map.put("2.1", 2.1);

Double min = Collections.min(map.values());
System.out.println(min); // 0.1

Обновление : поскольку вам также нужен ключ, я не вижу способов в Коллекции или Google Collections2 API, так как Карта ] не является Коллекцией . Maps # filterEntries () также бесполезен, так как фактический результат известен только на конце итерации.

Самым простым решением будет следующее:

Entry<String, Double> min = null;
for (Entry<String, Double> entry : map.entrySet()) {
    if (min == null || min.getValue() > entry.getValue()) {
        min = entry;
    }
}

System.out.println(min.getKey()); // 0.1

(проверка нуля на мин оставлена ​​в стороне)

47
ответ дан 29 November 2019 в 00:47
поделиться

При традиционном способе мне пришлось бы отсортировать карту по значениям, и брать первое/последнее. спасибо

Нет, не пришлось бы. Пришлось бы перебирать все значения и на каждом шаге сравнивать текущий элемент с наименьшим из тех, что мы видели до сих пор. Это O(n), по сравнению с O(n*log(n)) для сортировки - потенциально огромная разница.

BTW, именно так работает Collections.min().

5
ответ дан 29 November 2019 в 00:47
поделиться

Вы все еще можете использовать Collections.min с пользовательским Comparator, чтобы получить Map.Entry с меньшим значением:

Map<String, Double> map = new HashMap<String, Double>();
map.put("1.1", 1.1);
map.put("0.1", 0.1);
map.put("2.1", 2.1);
Entry<String, Double> min = Collections.min(map.entrySet(), new Comparator<Entry<String, Double>>() {
    public int compare(Entry<String, Double> entry1, Entry<String, Double> entry2) {
        return entry1.getValue().compareTo(entry2.getValue());
    }
});
System.out.printf("%s: %f", min.getKey(), min.getValue()); // 0.1: 0.100000

С Java 8:

Entry<String, Double> min = Collections.min(map.entrySet(),
                                       Comparator.comparing(Entry::getValue));
18
ответ дан 29 November 2019 в 00:47
поделиться

Чтобы сделать это эффективно, вы можете захотеть определить свою собственную структуру данных, чтобы она реализовывала интерфейс Map, но также позволяла эффективную операцию getMin ().

Это можно сделать с помощью двух внутренних структур данных: карты и дерева (или структуры данных кучи). Каждый раз, когда добавляется новая пара (K, V), добавляйте их на карту, а также в дерево (как одну запись). Это дает время O (1) для операций get (Key) и время O (log n) для операций добавления, удаления и getMin.

1
ответ дан 29 November 2019 в 00:47
поделиться

Я бы предпочел использовать Google Collections BiMap:

     String minKey = HashBiMap.create(map).inverse().get(Collections.min(map.values()));

Или что-то в этом роде (не тестировалось).

2
ответ дан 29 November 2019 в 00:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: