Группирование потоковBy: сокращение до первого элемента списка
У меня есть List<Valuta>
, который может быть представлен (упрощен) JSON-стиле:
[{codice = EUR, description = Euro, ratio = 1}, {codice = USD, description = Dollars, ratio = 1.1}]
Я хочу преобразовать это в Map<String, Valuta>
следующим образом:
{EUR = {codice = EUR, description = Euro, ratio = 1}, USD = {codice = USD, description = Dollars, ratio = 1.1}}
Я написал этот однострочный шрифт:
getValute().stream().collect(Collectors.groupingBy(Valuta::getCodice));
но это возвращает Map<String, List<Valuta>>
вместо того, что мне нужно.
Я полагаю, что функция mapping()
будет работать для меня, но не знаю, как это сделать.
Ответы
Ответ 1
На самом деле вам нужно использовать Collectors.toMap
здесь вместо Collectors.groupingBy
:
Map<String, Valuta> map =
getValute().stream()
.collect(Collectors.toMap(Valuta::getCodice, Function.identity()));
groupingBy
используется для группировки элементов потока на основе функции группировки. 2 Потоковые элементы, которые будут иметь одинаковый результат с функцией группировки, будут по умолчанию собраны в List
.
toMap
будет собирать элементы в Map
, где ключ является результатом применения заданного ключа, а значение - результат применения преобразователя значений. Обратите внимание, что toMap
, по умолчанию, генерирует исключение, если встречается дубликат.
Ответ 2
Вы можете использовать Collectors.toMap(keyMappingFunction, valueMappingFunction)
Map<String, Valuta> map = list
.stream()
.collect(Collectors.toMap(Valuta::getCodice, v -> v));
Вы можете заменить v->v
на Function.identity()
, если вы найдете его более читаемым.
Ответ 3
Немного поздно в игре, но попробуйте следующее:
Map<String, Valuta> map =
getValute().stream()
.collect(Collectors.groupingBy(Valuta::getCodice,
Collectors.collectingAndThen(
Collectors.toList(),
values -> values.get(0))));