Незмінний набір на Java

1. Вступ

У цьому підручнику ми розглянемо різні способи побудови незмінного набору в Java.

Але спочатку давайте розберемося в незмінному наборі і подивимося, навіщо він нам потрібен.

2. Що таке незмінний набір?

Загалом, незмінний об'єкт не змінить свого внутрішнього стану, коли ми його створимо. Це робить його потокобезпечним за замовчуванням. Така ж логіка застосовується до незмінних наборів.

Припустимо, у нас є екземпляр HashSet з деякими значеннями. Зробивши його незмінним, ми створимо версію набору для читання. Таким чином, будь-яка спроба змінити його стан призведе до UnsupportedOperationException .

Отже, навіщо це нам потрібно?

Звичайно, найпоширенішим випадком використання незмінного набору є багатопотокове середовище. Отже, ми можемо обмінюватися незмінними даними між потоками, не турбуючись про синхронізацію.

Тим часом слід пам’ятати важливий момент: незмінність стосується лише множини, а не її елементів . Крім того, ми можемо без проблем модифікувати посилання на екземпляри елементів набору.

3. Створіть незмінні набори в Core Java

Маючи у своєму розпорядженні лише основні класи Java, ми можемо використовувати колекції . unmodifiableSet () метод для обтікання вихідного набору .

Спочатку створимо простий екземпляр HashSet та ініціалізуємо його значеннями String :

Set set = new HashSet(); set.add("Canada"); set.add("USA");

Далі, давайте обернемо це колекціями . unmodifiableSet ():

Set unmodifiableSet = Collections.unmodifiableSet(set);

Нарешті, щоб переконатися , що наш unmodifiableSet екземпляр залишається незмінною, давайте створимо простий тестовий приклад:

@Test(expected = UnsupportedOperationException.class) public void testUnmodifiableSet() { // create and initialize the set instance Set unmodifiableSet = Collections.unmodifiableSet(set); unmodifiableSet.add("Costa Rica"); }

Як ми очікуємо, тест буде успішно запущений. Крім того, операція add () заборонена в екземплярі unmodifiableSet і викине UnsupportedOperationException .

Тепер давайте змінимо початковий екземпляр набору , додавши до нього те саме значення:

set.add("Costa Rica");

Таким чином, ми побічно модифікуємо немодифікований набір. Отже, коли ми друкуємо екземпляр unmodifiableSet :

[Canada, USA, Costa Rica]

Як бачимо, пункт “Коста-Ріка” також присутній у unmodifiableSet.

4. Створіть незмінні набори в Java 9

З Java 9 для створення незмінних наборів доступний статичний заводський метод Set.of (elements) :

Set immutable = Set.of("Canada", "USA");

5. Створіть незмінні набори в Гуаві

Інший спосіб побудови незмінного набору - це використання класу ImmutableSet від Guava . Він копіює наявні дані в новий незмінний екземпляр. Як результат, дані всередині ImmutableSet не змінюватимуться, коли ми змінимо вихідний набір .

Як і основна реалізація Java, будь-яка спроба модифікувати створений незмінний екземпляр викине UnsupportedOperationException .

Тепер давайте дослідимо різні способи створення незмінних примірників.

5.1. Використання ImmutableSet. copyOf ()

Простіше кажучи, ImmutableSet . метод copyOf () повертає копію всіх елементів набору:

Set immutable = ImmutableSet.copyOf(set);

Отже, після зміни початкового набору незмінний примірник залишиться незмінним:

[Canada, USA]

5.2. Використання ImmutableSet .of ()

Аналогічно, за допомогою методу ImmutableSet.of () ми можемо миттєво створити незмінний набір із заданими значеннями:

Set immutable = ImmutableSet.of("Canada", "USA");

Коли ми не вказуємо жодних елементів, ImmutableSet.of () поверне порожній незмінний набір.

Це можна порівняти з набором .of () Java 9 .

6. Висновок

У цій короткій статті ми обговорили незмінні набори мовою Java. Більше того, ми показали, як створювати незмінні набори, використовуючи API колекцій з базових Java, Java 9 та бібліотеки Guava.

Нарешті, як завжди, повний код цієї статті доступний на GitHub.