Как преобразовать карту в список в Java 8
Как преобразовать a Map<String, Double>
в List<Pair<String, Double>>
в Java 8?
Я написал эту реализацию, но она не эффективна
Map<String, Double> implicitDataSum = new ConcurrentHashMap<>();
//....
List<Pair<String, Double>> mostRelevantTitles = new ArrayList<>();
implicitDataSum.entrySet().stream().
.sorted(Comparator.comparing(e -> -e.getValue()))
.forEachOrdered(e -> mostRelevantTitles.add(new Pair<>(e.getKey(), e.getValue())));
return mostRelevantTitles;
Я знаю, что он должен работать с помощью .collect(Collectors.someMethod())
. Но я не понимаю, как это сделать.
Ответы
Ответ 1
Ну, вы хотите собрать элементы Pair
в List
. Это означает, что вам нужно сопоставить ваш Stream<Map.Entry<String, Double>>
с Stream<Pair<String, Double>>
.
Это делается с помощью операции map
:
Возвращает поток, состоящий из результатов применения данной функции к элементам этого потока.
В этом случае функция будет функцией, преобразующей a Map.Entry<String, Double>
в Pair<String, Double>
.
Наконец, вы хотите собрать это в List
, поэтому мы можем использовать встроенный коллекционер toList()
.
List<Pair<String, Double>> mostRelevantTitles =
implicitDataSum.entrySet()
.stream()
.sorted(Comparator.comparing(e -> -e.getValue()))
.map(e -> new Pair<>(e.getKey(), e.getValue()))
.collect(Collectors.toList());
Обратите внимание, что вы можете заменить компаратор Comparator.comparing(e -> -e.getValue())
на Map.Entry.comparingByValue(Comparator.reverseOrder())
.
Ответ 2
Обратите внимание: если вам нужна эффективная реализация, вы должны подумать об этом:
List<Pair<String, Double>> mostRelevantTitles =
implicitDataSum.entrySet()
.stream()
.map(e -> new Pair<>(e.getKey(), e.getValue()))
.collect(Collectors.toList());
mostRelevantTitles.sort(Comparators.comparing(Pair::getSecond, Comparator.reverseOrder()));
Я предполагаю, что ваш класс Pair
имеет getSecond
getter.
Используя шаг конвейера потока sorted()
, вы создаете промежуточный буфер, сохраняете все в этом буфере, преобразуете его в массив, сортируете этот массив, а затем сохраняете результат в ArrayList
. Мой подход, хотя и менее функциональный, хранит данные непосредственно в целевой ArrayList
, а затем сортирует его на месте без какого-либо дополнительного копирования. Таким образом, мое решение займет меньше времени и промежуточную память.