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

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

1. Вступление

В этой быстрой статье мы рассмотрим различные способы сбораStreamsиз Java в неизменяемыеCollections –, которые требуют особого подхода, поскольку стандартныеCollectorsработают только с изменяемыми структурами данных.

2. Maven Dependency

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


    com.google.guava
    guava
    22.0

Мы можем получить последнюю версию этой зависимости изhere.

3. ИспользованиеcollectingAndThen() в Java

МетодcollectingAndThen() из класса JavaCollectors принимаетCollector иfinisherFunction, которые применяются к результату, возвращенному изCollector:

@Test
public void whenUsingCollectingToImmutableList_thenSuccess() {
    List givenList = Arrays.asList("a", "b", "c");
    List result = givenList.stream()
      .collect(collectingAndThen(toList(), ImmutableList::copyOf));

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

Поскольку мы не можем использовать toCollection() Collector напрямую,, нам нужно собрать элементы во временный список, а затем построить из него неизменяемый список.

В этом примере мы конвертируемStream вList с помощью сборщикаtoList(), а затем создаемImmutableList. ImmutableList является частью библиотеки Guava. Если мы запишем вывод в консоль, мы получим класс базового

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

class com.google.common.collect.RegularImmutableList

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

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

@Test
public void whenCollectToImmutableList_thenSuccess() {
    List list = IntStream.range(0, 9)
      .boxed()
      .collect(ImmutableList.toImmutableList());
}

Результирующий экземпляр -RegularImmutableList:

class com.google.common.collect.RegularImmutableList

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

Теперь давайте сделаем еще один шаг и реализуем наш собственныйCollector. Для достижения этой цели мы собираемся использовать статический методCollector.of():

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

Чтобы узнать больше о реализации пользовательскогоCollectors, ознакомьтесь с разделом 4this article. Вот и все. Вышеуказанный метод является частью нашего пользовательского класса

Теперь мы можем использовать его, как любой другой встроенныйCollectors:

@Test
public void whenCollectToMyImmutableListCollector_thenSuccess() {
    List givenList = Arrays.asList("a", "b", "c", "d");
    List result = givenList.stream()
      .collect(MyImmutableListCollector.toImmutableList());
}

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

class java.util.Collections$UnmodifiableRandomAccessList