Использование Java 10 (неизменяемые наборы)
Set<String> strSet1 = Stream.of("A", "B", "C", "D")
.collect(Collectors.toUnmodifiableSet());
Здесь сборщик на самом деле возвращает немодифицируемый набор, введенный в Java 9, как видно из оператора set -> (Set<T>)Set.of(set.toArray())
в исходном коде.
Следует отметить, что заключается в том, что метод Collections.unmodifiableSet()
возвращает неизменяемое представление указанного набора (согласно документации). немодифицируемое представление коллекция - это коллекция, которую нельзя изменить, а также представление резервной коллекции. Обратите внимание, что изменения в резервной коллекции могут все еще возможны, и если они происходят, они видны через неизменяемое представление. Но метод Collectors.toUnmodifiableSet()
возвращает действительно неизменный , установленный в Java 10 .
Использование Java 9 (неизменяемые наборы)
Ниже приведен самый компактный способ инициализации набора:
Set<String> strSet6 = Set.of("Apple", "Ball", "Cat", "Dog");
У нас есть 12 перегруженных версий этой фабрики удобства метод:
static <E> Set<E> of()
static <E> Set<E> of(E e1)
static <E> Set<E> of(E e1, E e2)
// .... и так далее
static <E> Set<E> of(E... elems)
Тогда возникает естественный вопрос , почему нам нужны перегруженные версии, когда у нас есть var-args ? Ответ таков: каждый метод var-arg создает массив внутри, а наличие перегруженных версий позволит избежать ненужного создания объекта, а также избавит нас от затрат на сборку мусора.
Использование Java 8 (модифицируемые наборы)
Использование Stream в Java 8.
Set<String> strSet1 = Stream.of("A", "B", "C", "D")
.collect(Collectors.toCollection(HashSet::new));
// stream from an array (String[] stringArray)
Set<String> strSet2 = Arrays.stream(stringArray)
.collect(Collectors.toCollection(HashSet::new));
// stream from a list (List<String> stringList)
Set<String> strSet3 = stringList.stream()
.collect(Collectors.toCollection(HashSet::new));
Использование Java 8 (неизменяемые наборы)
Использование Collections.unmodifiableSet ()
Мы можем использовать Collections.unmodifiableSet()
как:
Set<String> strSet4 = Collections.unmodifiableSet(strSet1);
Но это выглядит немного неловко, и мы можем написать наш собственный сборщик, например:
class ImmutableCollector {
public static <T> Collector<T, Set<T>, Set<T>> toImmutableSet() {
return Collector.of(HashSet::new, Set::add, (l, r) -> {
l.addAll(r);
return l;
}, Collections::unmodifiablSet);
}
}
А затем используйте его как:
Set<String> strSet4 = Stream.of("A", "B", "C", "D")
.collect(ImmutableCollector.toImmutableSet());
Использование Collectors.collectingAndThen ()
Другой подход заключается в использовании метода Collectors.collectingAndThen()
, который позволяет нам выполнять дополнительные завершающие преобразования:
import static java.util.stream.Collectors.*;
Set<String> strSet5 = Stream.of("A", "B", "C", "D").collect(collectingAndThen(
toCollection(HashSet::new),Collections::unmodifiableSet));
Если мы заботимся только о Set
, то мы также можем использовать Collectors.toSet()
вместо Collectors.toCollection(HashSet::new)
.