Когда использовать Set vs. Collection?
Есть ли практическая разница между Set
а также Collection
в Java, кроме того факта, что Collection
можно включить один и тот же элемент дважды? У них одинаковые методы.
(Например, делает Set
дайте мне больше возможностей использовать библиотеки, которые принимают Set
с но не Collection
s?)
редактировать: я могу придумать как минимум 5 разных ситуаций, чтобы судить об этом вопросе. Кто-нибудь еще может придумать больше? Я хочу убедиться, что я понимаю тонкости здесь.
- разработка метода, который принимает аргумент
Set
или жеCollection
,Collection
является более общим и принимает больше возможностей ввода. (если я разрабатываю определенный класс или интерфейс, я буду более доброжелателен к своим потребителям и более строг в отношении моих субклассеров / разработчиков, если я используюCollection
.) - разработка метода, который возвращает
Set
или жеCollection
,Set
предлагает больше гарантий, чемCollection
(даже если это просто гарантия не включать один элемент дважды). (если я разрабатываю определенный класс или интерфейс, я буду более доброжелателен к своим потребителям и более строг в отношении моих субклассеров / разработчиков, если я используюSet
.) - проектирование класса, который реализует интерфейс
Set
или жеCollection
, Подобные проблемы, как #2. Пользователи моего класса / интерфейса получают больше гарантий, субклассеры / разработчики несут большую ответственность. - проектирование интерфейса, расширяющего интерфейс
Set
или жеCollection
, Очень похоже на № 3. - написание кода, который использует
Set
или жеCollection
, Здесь я мог бы также использоватьSet
; единственные причины для меня, чтобы использоватьCollection
если я вернусьCollection
из чужого кода, или если мне придется обрабатывать коллекцию, которая содержит дубликаты.
8 ответов
Collection
также супертип List
, Queue
, Deque
и другие, так что это дает вам больше возможностей. Например, я пытаюсь использовать Collection
в качестве параметра для библиотечных методов, которые не должны явно зависеть от определенного типа коллекции.
Как правило, вы должны использовать правильный инструмент для работы. Если вы не хотите дубликатов, используйте Set
(или же SortedSet
если вы хотите заказать, или LinkedHashSet
если вы хотите сохранить порядок вставки). Если вы хотите разрешить дубликаты, используйте List
, и так далее.
Я думаю, что вы уже поняли это - используйте Set
когда вы хотите специально исключить дубликаты. Collection
обычно является наименьшим общим знаменателем, и полезно указывать API, которые принимают / возвращают это, что оставляет вам возможность изменить детали позже, если это необходимо. Однако, если данные вашего приложения требуют уникальных записей, используйте Set
чтобы обеспечить это.
Также стоит подумать, важен ли для вас порядок; если это так, используйте List
, или же LinkedHashSet
если вы заботитесь о порядке и уникальности.
Еще одна вещь, которую следует учитывать... У наборов есть дополнительные накладные расходы во времени, памяти и кодировании, чтобы гарантировать отсутствие дубликатов. (Время и память, потому что наборы обычно поддерживаются HashMap или Tree, который добавляет накладные расходы на список или массив. Кодирование, потому что вы должны реализовать методы hashCode() и equals().)
Я обычно использую наборы, когда мне нужна быстрая реализация функции contains(), и использую Collection или List в противном случае, даже если в коллекции не должно быть дубликатов.
Посмотрите учебник Java's Collection для хорошего ознакомления с использованием Collection. В частности, проверьте иерархию классов.
Как утверждает @mmyers, коллекция включает в себя как Set, так и List.
Когда вы объявляете что-то как набор, а не как коллекцию, вы говорите, что переменная не может быть списком или картой. Впрочем, это всегда будет коллекция. Таким образом, любая функция, которая принимает коллекцию, примет набор, но функция, которая принимает набор, не может взять коллекцию (если вы не преобразуете ее в набор).
Вы должны использовать Набор, когда это то, что вы хотите.
Например, список без какого-либо заказа или дубликатов. Методы вроде содержит довольно полезные.
Коллекция гораздо более общая. Я верю, что то, что написал mmyers об их использовании, говорит обо всем.
Практическое отличие состоит в том, что Set обеспечивает реализацию логики набора, то есть не дублирует и не упорядочивает, а Collection - нет. Поэтому, если вам нужна коллекция, и у вас нет особых требований избегать дублирования, используйте коллекцию. Если у вас есть требование для Set, используйте Set. Как правило, используйте максимально возможный интерфейс.
Поскольку Collection - это супер тип Set и SortedSet, они могут быть переданы методу, который ожидает Collection. Коллекция просто означает, что она может или не может быть отсортирована, заказать или разрешить дубликаты.