Создание неизменного списка из существующего списка с использованием потоков - PullRequest
0 голосов
/ 26 октября 2018

Есть список Person объектов.

List<Person> persons = generatePersons();

С его помощью создается немодифицируемый список.

List<Person> unmodifiableList = Collections.unmodifiableList(persons);

Я понимаю, что unmodifiableList не поддерживает операции добавления / удаления / установки.В то же время он не является неизменным, поскольку имеет ссылку на существующий изменяемый список persons, и всякий раз, когда вносятся изменения в список persons, эти изменения также отражаются в unmodifiableList.

Таким образом создается неизменный список.

List<Person> immutableList = Collections.unmodifiableList(new ArrayList<>(persons));

Это создает неизменный список, так как используется конструктор преобразования.Операции добавления / удаления / установки не могут быть выполнены для immutableList, а любые изменения в исходном списке persons не будут отражены в immutableList.Давайте сделаем предположение, что Person объекты тоже неизменны.

Теперь я хочу создать эти два списка, используя потоки.

Первый, который я создал с помощью:

List<Person> unmodifiablePersons = persons.stream() .collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));

Я потерян при создании эквивалента immutableList через потоки.

Как я могу это сделать?

Редактировать:

Я добавил новый объект Person в исходный список persons и напечатал размер списка persons и unmodifiablePersons.Оба дают мне одинаковый размер.Итак, изменения отражаются в unmodifiablePersons и, следовательно, они еще не неизменны.Я что-то здесь упускаю?

Редактировать 2

Глупо.Должен был пройти через документы.unmodifiablePersons действительно неизменный список.Кроме того, новый объект Person был добавлен до того, как был создан unmodifiablePersons, и, следовательно, вышеупомянутое наблюдение.Супер глупо.

Ответы [ 2 ]

0 голосов
/ 26 октября 2018

С Java10 + вы могли бы использовать встроенную возможность copyOf для создания неизменяемого списка, например:

List<Person> persons = generatePersons();       
List<Person> unmodifiableList = List.copyOf(persons);

Кроме того, текущий список, который вы создаете с помощью Collector.collectingAndThen, на самом деле неизменен , как также указано в документации.

0 голосов
/ 26 октября 2018

Ну, в вашем первом случае кто-то имеет доступ к List<Person> unmodifiableList и может его редактировать, но когда вы collect, никто не имеет доступа к этому List, созданному Collectors.toList - так что выхорошо.

Что вам, вероятно, не хватает, так это то, что Collectors::toList создаст новый список - что на самом деле должно быть очевидным;и вы оборачиваете это в неизменяемый, таким образом, результат этого действительно неизменяем.

Также в java-10 есть специальный сборщик для этого:

List<Integer> result = Arrays.asList(1, 2, 3, 4)
        .stream()
        .collect(Collectors.toUnmodifiableList());

Этот сборщик использует List::of внутренне - неизменяемые коллекции добавлены в java-9, поэтому, например, они этого не делаютПоддержка нулей.

...