В чем отличие ImmutableList от Guava и Collections.unmodifiableList ()?

Рейтинг: 1Ответов: 1Опубликовано: 14.04.2023

Объясните, пожалуйста, есть ли какие-то отличия ImmutableList от Guava и Collections.unmodifiableList()?

Есть ли какие-то преимущества в использовании com.google.common.collect.ImmutableList перед java.util.Collections.unmodifiableList, или же между ними нет никакой разницы в части immutability, и они полностью взаимозаменяемы?

Ответы

▲ 4

Тема, поднятая в вопросе, на самом деле довольно глубокая и местами запутанная. Даже терминология immutable (неизменяемый) и unmodifiable (немодифицируемый) иногда плавает у создателей JDK/библиотек. Что же касается конкретно вашего вопроса, то да, разница есть. Всё зависит от "уровня защиты" объекта, который создаётся этими методами.

Для начала - что общего. И там и там создаются объекты интерфейса List, методы изменения (содержимого или размера) которых выбрасывают исключения. Это методы add, remove, set, sort и т.д.

Теперь об отличиях.

Метод Collections.unmodifiableList принимает в качестве аргумента другой list и хранит ссылку на него внутри новой реализации, оборачивая вызовы вышеперечисленных методов и бросая екцепшн. Но при этом изменив исходный лист мы получим изменение и в его unmodifiable отображении.

Библиотека Guava имеет 2 типа статических методов для создания отображения - of и copyOf. Первая группа методов принимает varargs элементов, которые будут содержаться в отображении, вторая группа - разные типы коллекции, iterable, list и т.п., из которых делается копия для хранения в отображении. Т.е. за исключением рефлексии невозможно повлиять на контент и размер отображения модифицируя источник.

props и cons:

Collections.unmodifiableList

малое потребление памяти

модификация отображения при воздействии на источник

может содержать nulls

Guava

большое потребление памяти

защита отображения при модификации источника

не может содержать nulls

Какой вариант выбирать - зависит от целей и баланса память/производительность/защита.

Ну и напоследок ещё парочка подобных методов.

List.of() - наверное полная аналогия Guava ImmutableList.of(). Если применить конструкцию (например для типа данных Integer) List.of(source.toArray(new Integer[0])), то это будет аналогия метода Guava ImmutableList.copyOf().

Arrays.asList() - создаёт list, содержимое которого можно модифицировать (методы set, sort), а размер нет (add, remove и т.д.)