Что такое изменяемые (mutable) коллекции в Java?

«Что такое изменяемые (mutable) коллекции в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Изменяемые (mutable) коллекции в Java — это коллекции, содержимое которых можно модифицировать после создания (добавлять, удалять, изменять элементы). Это стандартное поведение для большинства реализаций в java.util (например, ArrayList, HashMap, HashSet).

Пример изменяемого ArrayList:

List<String> mutableList = new ArrayList<>();
mutableList.add("Java");     // Добавление
mutableList.set(0, "Python"); // Изменение
mutableList.remove(0);       // Удаление
mutableList.clear();         // Очистка всей коллекции

Противоположность — неизменяемые (immutable) коллекции:

  • Java 9+: Фабричные методы List.of(), Set.of(), Map.of() создают неизменяемые коллекции. Попытка модификации выбросит UnsupportedOperationException.
  • Collections.unmodifiableX(): Возвращают представление, которое нельзя изменить.
    List<String> immutableList = List.of("A", "B", "C");
    // immutableList.add("D"); // Выбросит UnsupportedOperationException

    Когда использовать mutable коллекции?

  • Когда необходимо динамически изменять данные (наполнение коллекции в цикле, кэширование).
  • Для реализации сложных алгоритмов, требующих модификации структуры данных.

Важные аспекты при работе с mutable коллекциями:

  1. Потокобезопасность: Большинство mutable коллекций не являются потокобезопасными. Для работы в многопоточной среде требуется:
    • Использование коллекций из java.util.concurrent (ConcurrentHashMap, CopyOnWriteArrayList).
    • Внешняя синхронизация (Collections.synchronizedList()).
  2. Передача по ссылке: При передаче mutable коллекции в метод, изменения внутри этого метода отразятся на исходной коллекции, что может быть источником ошибок.
  3. Best practice: По возможности делайте коллекции неизменяемыми, особенно если они представляют конфигурацию или постоянные данные. Это упрощает рассуждение о коде и предотвращает случайные изменения.