Рубрики
Без рубрики

Преобразование списка в Карту С Настраиваемым поставщиком

Изучите несколько способов преобразования списка в карту с помощью пользовательских поставщиков.

Автор оригинала: baeldung.

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 Map groupingByStringLength(List source, 
    Supplier> mapSupplier, 
    Supplier listSupplier) {
    return source.stream()
        .collect(Collectors.groupingBy(String::length, mapSupplier, Collectors.toCollection(listSupplier)));
}

Мы можем подтвердить, что он работает с:

Map convertedMap = converter.groupingByStringLength(source, HashMap::new, ArrayList::new);
assertTrue(convertedMap.get(3).contains("Map"));

3.2. Коллекторы.toMap()

Метод Collectors.toMap уменьшает элементы в потоке в Карту.

Мы начнем с определения метода с исходной строки и Списка и Карты поставщиков:

public Map collectorToMapByStringLength(List source, 
        Supplier> mapSupplier, 
        Supplier listSupplier)

Затем мы определяем, как получить ключ и значение из элемента. Для этого мы используем две новые функции:

Function keyMapper = String::length;

Function valueMapper = (element) -> {
    List collection = listSupplier.get();
    collection.add(element);
    return collection;
};

Наконец, мы определяем функцию, которая вызывается при ключевом конфликте. В этом случае мы хотим объединить содержимое обоих:

BinaryOperator mergeFunction = (existing, replacement) -> {
    existing.addAll(replacement);
    return existing;
};

Собрав все вместе, мы получим:

source.stream().collect(Collectors.toMap(keyMapper, valueMapper, mergeFunction, mapSupplier))

Обратите внимание, что в большинстве случаев функции, которые мы определяем, являются анонимными онлайн-функциями внутри списка аргументов метода.

Давайте проверим это:

Map convertedMap = converter.collectorToMapByStringLength(source, HashMap::new, ArrayList::new);
assertTrue(convertedMap.get(3).contains("Map"));

3.3. Поток.сбор()

Метод Stream.collect можно использовать для сокращения элементов в потоке в Collection любого типа.

Для этого нам также нужно определить метод с List и Map поставщиками, который будет вызван, как только потребуется новая коллекция:

public Map streamCollectByStringLength(List source, 
        Supplier> mapSupplier, 
        Supplier listSupplier)

Затем мы переходим к определению аккумулятора , который, учитывая ключ к элементу, получает существующий список или создает новый и добавляет элемент в ответ:

BiConsumer, String> accumulator = (response, element) -> {
    Integer key = element.length();
    List values = response.getOrDefault(key, listSupplier.get());
    values.add(element);
    response.put(key, values);
};

Наконец, мы перейдем к объединению значений, генерируемых функцией аккумулятора:

BiConsumer, Map> combiner = (res1, res2) -> {
    res1.putAll(res2);
};

Собрав все вместе, мы затем просто вызываем метод collect в потоке наших элементов:

source.stream().collect(mapSupplier, accumulator, combiner);

Обратите внимание, что в большинстве случаев функции, которые мы определяем, являются анонимными онлайн-функциями внутри списка аргументов метода.

Результат теста будет таким же, как и в двух других методах:

Map convertedMap = converter.streamCollectByStringLength(source, HashMap::new, ArrayList::new);
assertTrue(convertedMap.get(3).contains("Map"));

4. Заключение

В этом уроке мы проиллюстрировали, как преобразовать List в Map List> с помощью API потока Java 8 с пользовательским Поставщиком s. List>

Полный исходный код с примерами из этого руководства можно найти на GitHub .