


Collectors.toMap строит Map из элементов потока. Две функции задают ключ и значение. Если несколько элементов дают одинаковый ключ, нужно определить правило объединения: вариант с двумя аргументами при таком конфликте выбрасывает IllegalStateException.
На Mentoring.digital разберём учебные строки поставки. У одного товара может быть несколько строк, поэтому здесь имеет смысл суммировать количество, а не случайно потерять одну из записей.
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class ToMapDemo {
record Line(String sku, int quantity) {}
public static void main(String[] args) {
var lines = List.of(
new Line("BOOK", 2),
new Line("PEN", 3),
new Line("BOOK", 4)
);
Map<String, Integer> quantities = lines.stream().collect(
Collectors.toMap(
Line::sku,
Line::quantity,
Integer::sum,
LinkedHashMap::new
)
);
System.out.println(quantities);
}
}
Пример использует record и рассчитан на Java 17 или новее. Результат: {BOOK=6, PEN=3}. Первая функция извлекает артикул, вторая количество, третья складывает значения при совпадении ключа, четвёртая создаёт Map нужного типа.
Функция (left, right) -> left оставляет ранее накопленное значение, а (left, right) -> right заменяет его новым. Для последовательного упорядоченного потока это позволяет выразить выбор первой или последней записи. Но «последняя в списке» не означает «самая свежая по времени».
Если нужна актуальная версия товара, сравнивайте поле версии или дату по правилам предметной области. При одинаковых датах тоже требуется решение. Если дубль запрещён требованиями, ошибка может быть правильным результатом: не скрывайте её объединением только ради успешного выполнения.
Обычные перегрузки toMap не обещают конкретный тип, изменяемость и потокобезопасность результирующей Map. Если порядок обхода важен для дальнейшего вывода, задайте подходящую фабрику явно. В нашем последовательном примере LinkedHashMap сохраняет порядок первого появления ключей.
Не переносите это наблюдение автоматически на произвольную параллельную обработку. Объединение значений должно быть согласовано с порядком потока и ассоциативно для корректного комбинирования частей. Операция «прибавить количество» и операция «выбрать запись по неоднозначной дате» требуют разных проверок.
Если по каждому ключу нужны все исходные записи, Map одного значения недостаточно. Тогда лучше использовать группировку в списки. В toMap правило объединения оправдано, когда вы действительно хотите получить одно итоговое значение на ключ.
Потоки и коллекции можно освоить на курсах Java. Проверить модель данных и правила обработки дублей поможет наставник по Java.