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

Соберите поток Java в неизменяемую коллекцию

Узнайте, как собирать потоки Java в неизменяемые коллекции.

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

1. введение

Мы часто хотим преобразовать Java поток в коллекцию. Обычно это приводит к изменяемой коллекции, но мы можем настроить ее.

В этом коротком уроке мы рассмотрим различные способы сбора Java потока в неизменяемую коллекцию .

2. Зависимость Maven

Мы собираемся использовать библиотеку Google Guava для приведения некоторых из наших примеров:


    com.google.guava
    guava
    22.0

Другие наши примеры взяты из стандартной библиотеки.

3. Использование сбора Java, А Затем

Метод collectingAndThen из класса Collectors Java принимает Collector и finisher | Функцию . Этот финишер применяется к результату, возвращенному из Сборщика:

List givenList = Arrays.asList("a", "b", "c");
List result = givenList.stream()
  .collect(collectingAndThen(toList(), ImmutableList::copyOf));

System.out.println(result.getClass());

При таком подходе, поскольку мы не можем использовать для сбора коллектора напрямую, нам нужно собрать элементы во временный список. Затем мы строим из него неизменяемый список.

Поэтому в этом примере мы преобразуем Stream в List с помощью сборщика ToList , а затем создаем ImmutableList . ImmutableList является частью библиотеки Guava.

Кроме того, если мы запишем выходные данные в консоль, мы получим класс базовой реализации List :

class com.google.common.collect.RegularImmutableList

4. Использование коллекторов Гуавы

Начиная с Guava 21, каждый неизменяемый класс поставляется с сопровождающим Collector , который так же прост в использовании, как и стандартный Collector s Java:

List list = IntStream.range(0, 9)
  .boxed()
  .collect(ImmutableList.toImmutableList());

Результирующим экземпляром является RegularImmutableList :

class com.google.common.collect.RegularImmutableList

5. Создание пользовательского коллектора

У нас также есть возможность реализовать пользовательский коллектор .

5.1. Базовый Неизменяемый Коллектор

Для достижения этой цели мы можем использовать метод static Collector.of :

public static  Collector, List> toImmutableList() {
    return Collector.of(ArrayList::new, List::add,
      (left, right) -> {
        left.addAll(right);
        return left;
      }, Collections::unmodifiableList);
}

Мы можем использовать эту функцию так же, как и любой встроенный Коллектор :

List givenList = Arrays.asList("a", "b", "c", "d");
List result = givenList.stream()
  .collect(MyImmutableListCollector.toImmutableList());

Наконец, давайте проверим тип вывода:

class java.util.Collections$UnmodifiableRandomAccessList

5.2. Сделать коллектор My ImmutableList универсальным

Наша реализация имеет одно ограничение – она всегда возвращает неизменяемый экземпляр, поддерживаемый ArrayList . Однако с небольшим улучшением мы можем заставить этот коллектор возвращать указанный пользователем тип:

Поэтому теперь вместо определения Поставщика в реализации метода мы запрашиваем Поставщика у пользователя:

List givenList = Arrays.asList("a", "b", "c", "d");
List result = givenList.stream()
  .collect(MyImmutableListCollector.toImmutableList(LinkedList::new));

Кроме того, мы используем Связанный список вместо ArrayList .

class java.util.Collections$UnmodifiableList

На этот раз мы получили unmodifiableList вместо UnmodifiableRandomAccessList .

6. Использование Java в немодифицируемом списке

Начиная с Java 10, мы можем использовать их для unmodifiableList метод из класса Java Collectors :

List givenList = Arrays.asList("a", "b", "c");
List result = givenList.stream()
  .collect(toUnmodifiableList());

Используя этот метод, мы получаем реализацию List , которая не поддерживает null значения из неизменяемых коллекций Java :

class java.util.ImmutableCollections$ListN

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

В этой короткой статье мы рассмотрели различные способы сбора Потока в неизменяемую Коллекцию .

Как всегда, полный исходный код этой статьи находится на GitHub. Они разделены по версии Java на примеры для разделов 2-5 и раздела 6 .