«1. Обзор

В этом кратком руководстве показано, как сделать ArrayList неизменяемым с помощью основного JDK, с помощью Guava и, наконец, с Apache Commons Collections 4.

Эта статья является частью «Java — Back to Basic». Серия € здесь, на Baeldung.

2. С помощью JDK

Во-первых, JDK предоставляет хороший способ получить неизменяемую коллекцию из существующей:

Collections.unmodifiableList(list);

На этом этапе новая коллекция больше не должна быть модифицируемой: ~~ ~

@Test(expected = UnsupportedOperationException.class)
public void givenUsingTheJdk_whenUnmodifiableListIsCreated_thenNotModifiable() {
    List<String> list = new ArrayList<>(Arrays.asList("one", "two", "three"));
    List<String> unmodifiableList = Collections.unmodifiableList(list);
    unmodifiableList.add("four");
}

2.1. С Java 9

Начиная с Java 9, мы можем использовать статический фабричный метод List\u003cE\u003e.of(E… elements) для создания неизменяемого списка:

@Test(expected = UnsupportedOperationException.class)
public final void givenUsingTheJava9_whenUnmodifiableListIsCreated_thenNotModifiable() {
    final List<String> list = new ArrayList<>(Arrays.asList("one", "two", "three"));
    final List<String> unmodifiableList = List.of(list.toArray(new String[]{}));
    unmodifiableList.add("four");
}

Обратите внимание, как мы должны преобразовать существующий список в массив. Это связано с тем, что List.of(elements) принимает параметры vararg.

3. С Guava

Guava предоставляет аналогичную функциональность для создания своей собственной версии ImmutableList:

ImmutableList.copyOf(list);

Аналогично — результирующий список не должен изменяться:

@Test(expected = UnsupportedOperationException.class)
public void givenUsingGuava_whenUnmodifiableListIsCreated_thenNotModifiable() {
    List<String> list = new ArrayList<>(Arrays.asList("one", "two", "three"));
    List<String> unmodifiableList = ImmutableList.copyOf(list);
    unmodifiableList.add("four");
}

Обратите внимание, что эта операция фактически создаст копию исходного списка, а не только представление.

Guava также предоставляет конструктор — он вернет строго типизированный ImmutableList вместо простого списка:

@Test(expected = UnsupportedOperationException.class)
public void givenUsingGuavaBuilder_whenUnmodifiableListIsCreated_thenNoLongerModifiable() {
    List<String> list = new ArrayList<>(Arrays.asList("one", "two", "three"));
    ImmutableList<String> unmodifiableList = ImmutableList.<String>builder().addAll(list).build();
    unmodifiableList.add("four");
}

4. С Apache Collections Commons

Наконец, Commons Collection также предоставляет API для создания неизменяемый список:

ListUtils.unmodifiableList(list);

И снова, изменение результирующего списка должно привести к исключению UnsupportedOperationException:

@Test(expected = UnsupportedOperationException.class)
public void givenUsingCommonsCollections_whenUnmodifiableListIsCreated_thenNotModifiable() {
    List<String> list = new ArrayList<>(Arrays.asList("one", "two", "three"));
    List<String> unmodifiableList = ListUtils.unmodifiableList(list);
    unmodifiableList.add("four");
}

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

В этом руководстве показано, как легко создать неизменяемый список из существующего списка ArrayList. с использованием основного JDK, Google Guava или Apache Commons Collections.

Реализацию всех этих примеров и фрагментов кода можно найти на Github — это проект на основе Maven, поэтому его легко импортировать и запускать как есть.