Groovy имеет расширенные методы сбора, то есть добавил методы к стандартным классам сбора.
Один из этих методов - toSet()
:
Конвертировать коллекцию в набор. Всегда возвращает новый набор , даже если коллекция уже является набором.
Пример использования:
def result = [1, 2, 2, 2, 3].toSet()
assert result instanceof Set
assert result == [1, 2, 3] as Set
Когда вы пишете это:
Set<String> unmodifiableFruits = Collections.unmodifiableCollection(fruits)
это подразумевает .toSet()
вызов, чтобы принудительно Collection
, возвращаемый unmodifiableCollection
, Set
, неявно копировать данные .
Когда вы пишете это:
Set<String> unmodifiableFruits = Collections.unmodifiableSet(fruits)
возвращаемое значение уже Set
, поэтому toSet()
не вызывается, что означает, что unmodifiableFruits
и fruits
совместно используют данные.
Вот почему вы должны явно копировать данные при использовании unmodifiableSet
, добавив new HashSet(...)
.
Правильно ли используется Collections.unmodifiableCollection()
при передаче набора в конструктор?
Абсолютно нет. Использование unmodifiableCollection()
и присвоение Set
, неявно вызывающий toSet
, который копирует данные, скрывает факт выполнения копии.
Чтобы обеспечить читабельность кода, т. Е. Чтобы каждый, кто читает код (включая вас самих за 3 года), понял, что он делает, напишите код для явного копирования данных, используя конструктор копирования.
Ну, конечно, если только это не упражнение по запутыванию кода, в этом случае это обманчивый трюк.