Перейти к основному содержимому

Инициализация HashSet во время построения

· 3 мин. чтения

Задача: Сумма двух чисел

Напишите функцию twoSum. Которая получает массив целых чисел nums и целую сумму target, а возвращает индексы двух чисел, сумма которых равна target. Любой набор входных данных имеет ровно одно решение, и вы не можете использовать один и тот же элемент дважды. Ответ можно возвращать в любом порядке...

ANDROMEDA

1. Обзор

В этом кратком руководстве мы представим различные методы инициализации HashSet со значениями во время его создания.

Чтобы вместо этого изучить возможности HashSet , обратитесь к этой основной статье здесь .

Мы рассмотрим встроенные методы Java начиная с Java 5 и ранее , а затем рассмотрим новые механизмы, представленные начиная с Java 8.

Мы также увидим пользовательский служебный метод и, наконец, изучим функции, предоставляемые сторонними библиотеками коллекций , в частности Google Guava.

Если мы уже перешли на JDK9+, мы можем просто использовать методы фабрики коллекций.

2. Встроенные методы Java

Давайте начнем с изучения трех встроенных механизмов, доступных начиная с Java 5 или ранее.

2.1. Использование другого экземпляра коллекции

Мы можем передать существующий экземпляр другой коллекции для инициализации Set .

Здесь мы используем встроенный List :

Set<String> set = new HashSet<>(Arrays.asList("a", "b", "c"));

2.2. Использование анонимного класса

В еще одном подходе мы можем использовать анонимный класс для добавления элемента в HashSet .

Обратите внимание на использование двойных фигурных скобок. Этот подход технически очень дорог , потому что он создает анонимный класс при каждом вызове.

Итак, в зависимости от того, как часто нам нужно инициализировать Set , мы можем попытаться избежать использования этого подхода :

Set<String> set = new HashSet<String>(){{
add("a");
add("b");
add("c");
}};

2.3. Использование метода утилиты коллекций, начиная с Java 5

Вспомогательный класс Java Collections предоставляет метод singleton для создания Set с одним элементом . Экземпляр Set , созданный с помощью метода singleton , является immutable , что означает, что мы не можем добавлять к нему дополнительные значения.

Существуют ситуации, особенно при модульном тестировании, когда нам нужно создать набор с одним значением:

Set<String> set = Collections.singleton("a");

3. Определение пользовательского метода утилиты

Мы можем определить статический окончательный метод, как показано ниже. Метод принимает переменные аргументы.

Использование Collections.addAll , которое принимает объект коллекции и массив значений, является лучшим среди других из-за низких накладных расходов на копирование значений.

Метод использует дженерики , поэтому мы можем передавать значения любого типа:

public static final <T> Set<T> newHashSet(T... objs) {
Set<T> set = new HashSet<T>();
Collections.addAll(set, objs);
return set;
}

Вот как мы можем использовать служебный метод в нашем коде:

Set<String> set = newHashSet("a","b","c");

4. Использование Stream Начиная с Java 8

С введением Stream API в Java 8 у нас появились дополнительные опции, такие как Stream with Collectors :

Set<String> set = Stream.of("a", "b", "c")
.collect(Collectors.toCollection(HashSet::new));

5. Использование сторонней библиотеки коллекций

Существует несколько сторонних библиотек коллекций, включая Google Guava, Apache Commons Collections и Eclipse Collections, и это лишь некоторые из них.

Эти библиотеки предоставляют удобные служебные методы для инициализации коллекций, таких как Set. Поскольку Google Guava является одним из наиболее часто используемых, мы включили пример из него.

В Guava есть удобные методы для изменяемых и неизменяемых объектов Set :

Set<String> set = Sets.newHashSet("a", "b", "c");

Точно так же в Guava есть служебный класс для создания неизменяемых экземпляров Set :

Set<String> set = ImmutableSet.of("a", "b", "c");

6. Заключение

В этой статье мы увидели несколько способов инициализации HashSet во время его создания.

Эти подходы не обязательно охватывают все возможные способы. Эта статья — всего лишь попытка продемонстрировать наиболее распространенные способы.

Например, один подход, не рассмотренный здесь, может заключаться в использовании построителя объектов для создания Set .

Как всегда, рабочий пример кода доступен на GitHub .