Collectors.toUnmodifiableList в java-10

Как создать Unmodifiable List/Set/Map с Collectors.toList/toSet/toMap, поскольку toList (и тому подобное) являются документами как:

Нет гарантий относительно типа, изменчивости, сериализуемости или безопасности потоков возвращаемого списка.

Перед java-10 вам нужно предоставить Function Collectors.collectingAndThen, например:

 List<Integer> result = Arrays.asList(1, 2, 3, 4)
            .stream()
            .collect(Collectors.collectingAndThen(
                    Collectors.toList(),
                    x -> Collections.unmodifiableList(x)));

Ответ 1

С Java 10 это намного проще и читаемо:

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

Внутри это то же самое, что и Collectors.collectingAndThen, но возвращает экземпляр немодифицируемого List который был добавлен в Java 9.

Ответ 2

Кроме того, чтобы очистить документированную разницу между двумя (collectingAndThen против toUnmodifiableList) реализаций:

The Collectors.toUnmodifiableList вернет коллекционер, который запрещает использование нулевых значений и будет NullPointerException если оно представлено null значением.

static void additionsToCollector() {
    // this works fine unless you try and operate on the null element
    var previous = Stream.of(1, 2, 3, 4, null)
            .collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));

    // next up ready to face an NPE
    var current = Stream.of(1, 2, 3, 4, null).collect(Collectors.toUnmodifiableList());
}

и тем более, что из-за того, что первый строит экземпляр Collections.UnmodifiableRandomAccessList а последний создает экземпляр ImmutableCollections.ListN который добавляет к списку атрибутов, приносимых в таблицу со статическими фабричными методами.