1. Обзор
В этом уроке мы собираемся преобразовать List в Map List> . Мы достигнем этого с помощью потокового API Java и функционального интерфейса поставщика . List>
2. Поставщик в JDK 8
Поставщик часто используется в качестве завода. Метод может принимать Поставщик в качестве входных данных и ограничивает тип, используя ограниченный тип подстановочных знаков, затем клиент может передать фабрику, которая создает любой подтип данного типа.
Кроме того, Поставщик может выполнять ленивую генерацию значений .
3. Преобразование списка в карту
API потока обеспечивает поддержку манипуляций List . Одним из таких примеров является метод Stream#collect /. Однако в методах API потока нет способа напрямую передать Поставщикам нижестоящим параметрам.
В этом уроке мы рассмотрим методы Collectors.groupingBy , Collectors.toMap и Stream.collect с примерами фрагментов кода. Мы сосредоточимся на методах, которые позволяют нам использовать пользовательский Поставщик .
В этом уроке мы обработаем Список строк коллекции в следующих примерах:
List source = Arrays.asList("List", "Map", "Set", "Tree");
Мы объединим приведенный выше список в карту, ключом которой является длина строки. Когда мы закончим, у нас будет карта, которая выглядит так::
{ 3: ["Map", "Set"], 4: ["List", "Tree"] }
3.1. Коллекционеры.()
С помощью Collectors.groupingBy мы можем преобразовать Коллекцию в Карту с определенным классификатором. Классификатор-это атрибут элемента, мы будем использовать этот атрибут для включения элементов в различные группы:
public MapgroupingByStringLength(List source, Supplier
Мы можем подтвердить, что он работает с:
MapconvertedMap = converter.groupingByStringLength(source, HashMap::new, ArrayList::new); assertTrue(convertedMap.get(3).contains("Map"));
3.2. Коллекторы.toMap()
Метод Collectors.toMap уменьшает элементы в потоке в Карту.
Мы начнем с определения метода с исходной строки и Списка и Карты поставщиков:
public MapcollectorToMapByStringLength(List source, Supplier
Затем мы определяем, как получить ключ и значение из элемента. Для этого мы используем две новые функции:
FunctionkeyMapper = String::length; Function valueMapper = (element) -> { List collection = listSupplier.get(); collection.add(element); return collection; };
Наконец, мы определяем функцию, которая вызывается при ключевом конфликте. В этом случае мы хотим объединить содержимое обоих:
BinaryOperatormergeFunction = (existing, replacement) -> { existing.addAll(replacement); return existing; };
Собрав все вместе, мы получим:
source.stream().collect(Collectors.toMap(keyMapper, valueMapper, mergeFunction, mapSupplier))
Обратите внимание, что в большинстве случаев функции, которые мы определяем, являются анонимными онлайн-функциями внутри списка аргументов метода.
Давайте проверим это:
MapconvertedMap = converter.collectorToMapByStringLength(source, HashMap::new, ArrayList::new); assertTrue(convertedMap.get(3).contains("Map"));
3.3. Поток.сбор()
Метод Stream.collect можно использовать для сокращения элементов в потоке в Collection любого типа.
Для этого нам также нужно определить метод с List и Map поставщиками, который будет вызван, как только потребуется новая коллекция:
public MapstreamCollectByStringLength(List source, Supplier
Затем мы переходим к определению аккумулятора , который, учитывая ключ к элементу, получает существующий список или создает новый и добавляет элемент в ответ:
BiConsumer
Наконец, мы перейдем к объединению значений, генерируемых функцией аккумулятора:
BiConsumer
Собрав все вместе, мы затем просто вызываем метод collect в потоке наших элементов:
source.stream().collect(mapSupplier, accumulator, combiner);
Обратите внимание, что в большинстве случаев функции, которые мы определяем, являются анонимными онлайн-функциями внутри списка аргументов метода.
Результат теста будет таким же, как и в двух других методах:
MapconvertedMap = converter.streamCollectByStringLength(source, HashMap::new, ArrayList::new); assertTrue(convertedMap.get(3).contains("Map"));
4. Заключение
В этом уроке мы проиллюстрировали, как преобразовать List в Map List> с помощью API потока Java 8 с пользовательским Поставщиком s. List>
Полный исходный код с примерами из этого руководства можно найти на GitHub .