Можно ли изменить данные в иммутабельной коллекции?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Иммутабельные коллекции в Java
Что это такое?
Иммутабельная коллекция — это коллекция, состояние которой не может быть изменено после её создания. Это не означает, что содержащиеся в ней объекты неизменяемы, а то, что саму коллекцию нельзя модифицировать — нельзя добавлять, удалять или переставлять элементы.
Можно ли изменить данные в иммутабельной коллекции?
Ответ: нет и да одновременно.
Нет — стандартных методов изменения коллекции:
List<String> unmodifiable = Collections.unmodifiableList(
new ArrayList<>(Arrays.asList("A", "B", "C"))
);
unmodifiable.add("D"); // UnsupportedOperationException
unmodifiable.remove(0); // UnsupportedOperationException
Да — если объекты внутри коллекции mutable:
List<User> users = Collections.unmodifiableList(
new ArrayList<>(Arrays.asList(user1, user2))
);
users.get(0).setName("New Name"); // Сработает!
users.add(user3); // UnsupportedOperationException — коллекция иммутабельна
Способы создания иммутабельных коллекций в Java
1. Collections.unmodifiable*
List<String> list = Collections.unmodifiableList(
new ArrayList<>(Arrays.asList("A", "B"))
);
Set<String> set = Collections.unmodifiableSet(
new HashSet<>(Arrays.asList("A", "B"))
);
Map<String, Integer> map = Collections.unmodifiableMap(
new HashMap<>(){{put("key", 1);}}
);
2. Java 9+ — List.of(), Set.of(), Map.of()
List<String> list = List.of("A", "B", "C");
Set<String> set = Set.of("A", "B", "C");
Map<String, Integer> map = Map.of("key1", 1, "key2", 2);
Это более безопасный вариант — коллекции также не содержат null элементов.
3. Stream API
List<String> list = Stream.of("A", "B", "C")
.collect(Collections.toUnmodifiableList());
Важные различия
| Параметр | Collections.unmodifiable* | List.of() / Set.of() |
|---|---|---|
| null элементы | 允许 | Не допускаются |
| Скорость | Обертка, есть overhead | Оптимизирована |
| Гарантия | Слабая | Полная |
Когда использовать?
- Параметры методов: защита от неожиданных модификаций
public void process(List<String> items) {
List<String> safe = Collections.unmodifiableList(items);
// Теперь гарантия что items не изменится
}
- API возвращаемые значения: контроль кто может менять внутреннее состояние
public List<User> getUsers() {
return Collections.unmodifiableList(internalList);
}
- Constant коллекции: статические неизменяемые данные
public static final List<String> ROLES = List.of("ADMIN", "USER", "GUEST");
Выводы
Иммутабельная коллекция гарантирует неизменяемость только структуры коллекции, не содержимого. Если нужна полная иммутабельность, используй неизменяемые объекты (final поля, нет setters) внутри иммутабельной коллекции. Для новых проектов предпочитай Java 9+ List.of()/Set.of() вместо Collections.unmodifiable*.