← Назад к вопросам

Как получить неизменяемый список из ArrayList?

1.0 Junior🔥 201 комментариев
#Коллекции

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Получение неизменяемого списка из ArrayList

Основные способы

1. Collections.unmodifiableList() — классический подход

Это наиболее распространённый способ, работает со всеми версиями Java:

ArrayList<String> mutableList = new ArrayList<>();
mutableList.add("Apple");
mutableList.add("Banana");

// Получаем неизменяемый лист
List<String> immutableList = Collections.unmodifiableList(mutableList);

// Попытка модификации вызовет UnsupportedOperationException
immutableList.add("Cherry"); // ❌ Исключение!

Важный нюанс: это не глубокая копия. Если изменить исходный ArrayList, изменения будут видны в неизменяемом списке:

ArrayList<String> mutableList = new ArrayList<>();
mutableList.add("Apple");

List<String> immutableList = Collections.unmodifiableList(mutableList);

mutableList.add("Banana");

// immutableList теперь содержит ["Apple", "Banana"]
System.out.println(immutableList); // [Apple, Banana]

Если нужна настоящая неизменяемость с защитой от внешних изменений, создайте копию:

List<String> trueImmutable = Collections.unmodifiableList(
    new ArrayList<>(mutableList)
);

2. List.copyOf() — современный подход (Java 10+)

Это рекомендуемый способ для современного кода:

ArrayList<String> mutableList = new ArrayList<>();
mutableList.add("Apple");
mutableList.add("Banana");

// Создаёт неизменяемую копию
List<String> immutableList = List.copyOf(mutableList);

// Попытка модификации вызовет UnsupportedOperationException
immutableList.add("Cherry"); // ❌ Исключение!

// Изменения в исходном списке НЕ повлияют на копию
mutableList.add("Orange");
System.out.println(immutableList); // [Apple, Banana]

Преимущества List.copyOf():

  • Создаёт настоящую копию
  • Гарантирует полную неизменяемость
  • Оптимизирован для производительности
  • Если передана null ссылка, выбросит NullPointerException

3. Stream API (Java 8+)

ArrayList<String> mutableList = new ArrayList<>();
mutableList.add("Apple");
mutableList.add("Banana");

List<String> immutableList = mutableList.stream()
    .collect(Collectors.toUnmodifiableList());

// Или с jdk.incubator (Java 10+)
List<String> immutableList2 = mutableList.stream()
    .collect(Collectors.toList()); // Создаёт неизменяемый список

4. List.of() — для инициализации (Java 9+)

Если нужно сразу создать неизменяемый список:

// Не из ArrayList, но альтернатива
List<String> immutableList = List.of(
    "Apple", "Banana", "Cherry"
);

immutableList.add("Orange"); // ❌ UnsupportedOperationException

Сравнение подходов

СпособJavaКопируетЗащитаРекомендация
Collections.unmodifiableList()1.2+НетЧастичнаяСтарый код
List.copyOf()10+ДаПолная✅ Лучший выбор
Stream.toUnmodifiableList()10+ДаПолнаяДля потоков
List.of()9+ДаПолнаяДля инициализации

Производительность

// Контрольный пример
ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i < 1_000_000; i++) {
    list.add(i);
}

long start = System.nanoTime();
List<Integer> unmodifiable = Collections.unmodifiableList(list);
long time1 = System.nanoTime() - start; // ~100 ns (просто обёртка)

start = System.nanoTime();
List<Integer> copyOf = List.copyOf(list);
long time2 = System.nanoTime() - start; // ~10 ms (копирует данные)

Collections.unmodifiableList() быстрее, но List.copyOf() безопаснее.

Рекомендации

  1. Используйте List.copyOf() — если нужна настоящая неизменяемость и Java 10+
  2. Используйте Collections.unmodifiableList() — для старого кода, но помните о ссылках
  3. Передавайте неизменяемые списки в методы параметром, чтобы гарантировать целостность данных
  4. Избегайте null в неизменяемых списках (List.copyOf() не допускает null элементов)

Соврменный стандартный подход — List.copyOf() для его надёжности и простоты.

Как получить неизменяемый список из ArrayList? | PrepBro