1. введение
В этом уроке мы рассмотрим различные способы построения неизменяемого набора в Java.
Но сначала давайте разберемся в неизменяемом наборе и посмотрим, зачем он нам нужен.
2. Что такое Неизменяемое множество?
В общем случае неизменяемый объект не изменит свое внутреннее состояние после его создания. Это делает его потокобезопасным по умолчанию. Та же логика применима и к неизменяемым множествам.
Предположим, у нас есть экземпляр HashSet с некоторыми значениями. Сделав его неизменяемым, мы создадим версию нашего набора “только для чтения”. Таким образом, любая попытка изменить его состояние вызовет UnsupportedOperationException .
Итак, зачем нам это нужно?
Конечно, наиболее распространенным вариантом использования неизменяемого набора является многопоточная среда. Таким образом, мы можем обмениваться неизменяемыми данными между потоками, не беспокоясь о синхронизации.
Между тем, следует иметь в виду важный момент: неизменность относится только к множеству, а не к его элементам . Кроме того, мы можем без проблем изменять ссылки на экземпляры элементов набора.
3. Создайте неизменяемые наборы в ядре Java
Имея в своем распоряжении только основные классы Java, мы можем использовать Сборники . Немодифицируемый набор() способ обертывания оригинала Набор .
Во-первых, давайте создадим простой экземпляр HashSet и инициализируем его значениями String :
Setset = new HashSet<>(); set.add("Canada"); set.add("USA");
Затем давайте завершим его с помощью Collections . Немодифицируемый набор():
SetunmodifiableSet = Collections.unmodifiableSet(set);
Наконец, чтобы убедиться, что наш экземпляр unmodifiableSet неизменяем, давайте создадим простой тестовый случай:
@Test(expected = UnsupportedOperationException.class) public void testUnmodifiableSet() { // create and initialize the set instance SetunmodifiableSet = Collections.unmodifiableSet(set); unmodifiableSet.add("Costa Rica"); }
Как мы и ожидали, тест пройдет успешно. Кроме того, операция add() запрещена в экземпляре |/unmodifiableSet и вызовет исключение UnsupportedOperationException .
Теперь давайте изменим начальный экземпляр set , добавив к нему то же значение:
set.add("Costa Rica");
Таким образом, мы косвенно модифицируем неизменяемый набор. Итак, когда мы печатаем экземпляр unmodifiableSet :
[Canada, USA, Costa Rica]
Как мы видим, элемент “Коста-Рика” также присутствует в unmodifiableSet.
4. Создайте неизменяемые наборы в Java 9
Начиная с Java 9, метод Set.of(elements) static factory доступен для создания неизменяемых наборов:
Setimmutable = Set.of("Canada", "USA");
5. Создайте неизменяемые наборы в Гуаве
Другой способ, которым мы можем построить неизменяемый набор, – это использование класса ImmutableSet Гуавы//. Он копирует существующие данные в новый неизменяемый экземпляр. В результате данные внутри ImmutableSet не изменятся, когда мы изменим исходный Set .
Как и в основной реализации Java, любая попытка изменить созданный неизменяемый экземпляр вызовет исключение UnsupportedOperationException .
Теперь давайте рассмотрим различные способы создания неизменяемых экземпляров.
5.1. Использование ImmutableSet.copyOf()
Проще говоря, НеизменяеМый набор . copyOf() метод возвращает копию всех элементов в наборе:
Setimmutable = ImmutableSet.copyOf(set);
Таким образом, после изменения исходного набора неизменяемый экземпляр останется прежним:
[Canada, USA]
5.2. Использование Неизменный набор.()
Аналогично, с помощью метода ImmutableSet.of() мы можем мгновенно создать неизменяемый набор с заданными значениями:
Setimmutable = ImmutableSet.of("Canada", "USA");
Когда мы не указываем никаких элементов, ImmutableSet.of() вернет пустой неизменяемый набор.
Это можно сравнить с Java 9 Set .of().
6. Заключение
В этой краткой статье мы обсудили неизменяемые Наборы на языке Java. Кроме того, мы показали, как создавать неизменяемые Наборы с помощью API коллекций из core Java, Java 9 и библиотеки Guava.
Наконец, как обычно, полный код этой статьи доступен на GitHub .