что такое set в java
Множества: Set, HashSet, LinkedHashSet, TreeSet
HashSet, TreeSet и LinkedHashSet относятся к семейству Set. В множествах Set каждый элемент хранится только в одном экземпляре, а разные реализации Set используют разный порядок хранения элементов. В HashSet порядок элементов определяется по сложному алгоритму. Если порядок хранения для вас важен, используйте контейнер TreeSet, в котором объекты хранятся отсортированными по возрастанию в порядке сравнения или LinkedHashSet с хранением элементов в порядке добавления.
Множества часто используются для проверки принадлежности, чтобы вы могли легко проверить, принадлежит ли объект заданному множеству, поэтому на практике обычно выбирается реализация HashSet, оптимизированная для быстрого поиска.
В Android 11 (R) обещают добавить несколько перегруженных версий метода of(), которые являются частью Java 8.
HashSet
Название Hash. происходит от понятия хэш-функция. Хэш-функция — это функция, сужающая множество значений объекта до некоторого подмножества целых чисел. Класс Object имеет метод hashCode(), который используется классом HashSet для эффективного размещения объектов, заносимых в коллекцию. В классах объектов, заносимых в HashSet, этот метод должен быть переопределен (override).
Имеет два основных конструктора (аналогично ArrayList):
Методы
Методы аналогичны методам ArrayList за исключением того, что метод add(Object o) добавляет объект в множество только в том случае, если его там нет. Возвращаемое методом значение — true, если объект добавлен, и false, если нет.
Итак, создадим множество стран.
Нажав на кнопку, вы получите результат Размер HashSet = 4.
Даже если вы попытаетесь схитрить и дополнительно вставить строку countryHashSet.add(«Кот-Д’Ивуар»); после России, то всё-равно размер останется прежним.
Убедиться в этом можно, если вызвать метод iterator(), который позволяет получить всё множество элементов:
Несмотря на наше упрямство, мы видим только четыре добавленных элемента.
Стоит отметить, что порядок добавления стран во множество будет непредсказуемым. HashSet использует хэширование для ускорения выборки. Если вам нужно, чтобы результат был отсортирован, то пользуйтесь TreeSet.
Преобразовать в массив и вывести в ListView
Продолжим опыты. Поработаем теперь с числами.
Здесь мы ещё раз убеждаемся, что повторное добавление числа не происходит. В цикле случайным образом выбирается число от 0 до 9 тысячу раз. Естественно, многие числа должны были повториться при таком сценарии, но во множество каждое число попадёт один раз.
При этом данные не сортируются, так как расположены как попало.
Специально для Android был разработан новый класс ArraySet, который более эффективен.
LinkedHashSet
Класс LinkedHashSet расширяет класс HashSet, не добавляя никаких новых методов. Класс поддерживает связный список элементов набора в том порядке, в котором они вставлялись. Это позволяет организовать упорядоченную итерацию вставки в набор.
TreeSet
Переделанный пример для вывода случайных чисел в отсортированном порядке. HashSet не может гарантировать, что данные будут отсортированы, так как работает по другому алгоритму. Если сортировка для вас важна, то используйте TreeSet.
Со строками это выглядит нагляднее:
Названия стран выведутся в алфавитном порядке.
Класс TreeSet создаёт коллекцию, которая для хранения элементов применяет дерево. Объекты сохраняются в отсортированном порядке по возрастанию.
SortedSet
В примере с TreeSet использовался интерфейс SortedSet, который позволяет сортировать элементы множества. По умолчанию сортировка производится привычным способом, но можно изменить это поведение через интерфейс Comparable.
Кроме стандартных методов Set у интерфейса есть свои методы.
Набор данных интерфейса Set
Реализация интерфейса Set представляет собой неупорядоченную коллекцию, которая не может содержать дублирующие данные.
Интерфейс Set включает следующие методы :
Метод | Описание |
---|---|
add(Object o) | Добавление элемента в коллекцию, если он отсутствует. Возвращает true, если элемент добавлен. |
addAll(Collection c) | Добавление элементов коллекции, если они отсутствуют. |
clear() | Очистка коллекции. |
contains(Object o) | Проверка присутствия элемента в наборе. Возвращает true, если элемент найден. |
containsAll(Collection c) | Проверка присутсвия коллекции в наборе. Возвращает true, если все элементы содержатся в наборе. |
equals(Object o) | Проверка на равенство. |
hashCode() | Получение hashCode набора. |
isEmpty() | Проверка наличия элементов. Возвращает true если в коллекции нет ни одного элемента. |
iterator() | Функция получения итератора коллекции. |
remove(Object o) | Удаление элемента из набора. |
removeAll(Collection c) | Удаление из набора всех элементов переданной коллекции. |
retainAll(Collection c) | Удаление элементов, не принадлежащих переданной коллекции. |
size() | Количество элементов коллекции |
toArray() | Преобразование набора в массив элементов. |
toArray(T[] a) | Преобразование набора в массив элементов. В отличии от предыдущего метода, который возвращает массив объектов типа Object, данный метод возвращает массив объектов типа, переданного в параметре. |
К семейству интерфейса Set относятся HashSet, TreeSet и LinkedHashSet. В множествах Set разные реализации используют разный порядок хранения элементов. В HashSet порядок элементов оптимизирован для быстрого поиска. В контейнере TreeSet объекты хранятся отсортированными по возрастанию. LinkedHashSet хранит элементы в порядке добавления.
Набор данных HashSet
Конструкторы HashSet :
Методы HashSet
HashSet содержит методы аналогично ArrayList. Исключением является метод add(Object o), который добавляет объект только в том случае, если он отсутствует. Если объект добавлен, то метод add возвращает значение — true, в противном случае false.
Пример использования HashSet :
В консоли мы должны увидеть только 4 записи. Следует отметить, что порядок добавления записей в набор будет непредсказуемым. HashSet использует хэширование для ускорения выборки.
Следует отметить, что реализация HashSet не синхронизируется. Если многократные потоки получают доступ к набору хеша одновременно, а один или несколько потоков должны изменять набор, то он должен быть синхронизирован внешне. Это лучше всего выполнить во время создания, чтобы предотвратить случайный несинхронизируемый доступ к набору :
Набор данных LinkedHashSet
Класс LinkedHashSet наследует HashSet, не добавляя никаких новых методов, и поддерживает связный список элементов набора в том порядке, в котором они вставлялись. Это позволяет организовать упорядоченную итерацию вставки в набор.
Также, как и HashSet, LinkedHashSet не синхронизируется. Поэтому при использовании данной реализации в приложении с множеством потоков, часть из которых может вносить изменения в набор, следует на этапе создания выполнить синхронизацию :
Набор данных TreeSet
Класс TreeSet создаёт коллекцию, которая для хранения элементов использует дерево. Объекты хранятся в отсортированном порядке по возрастанию.
Конструкторы TreeSet :
Методы TreeSet
В следующем измененном примере с использования TreeSet в консоль будут выведены значения в упорядоченном виде.
Коллекция HashSet
1. Контейнеры и коллекции
Контейнерами или коллекциями называют классы, которые позволяют хранить и обрабатывать много объектов сразу. Вы уже знаете две разновидности контейнеров — массивы и списки.
В Java есть несколько десятков коллекций, каждая из которых хранит элементы своим специфическим способом. Вот некоторые из них:
Тип коллекции | Класс | Описание |
---|---|---|
Список | ||
Связный список | ||
Вектор | ||
Стэк (стопка) | ||
Множество | ||
Очередь | ||
Карта/Словарь |
Поэтому коллекции разделились на коллекции в широком смысле и коллекции в узком смысле (только те, которые реализуют интерфейс Collection ).
2. Коллекция HashSet
Создать объект типа HashSet можно с помощью команды вида:
У класса HashSet есть такие методы:
Пример использования множества.
Давайте напишем программу, которая прощается с пользователем, если он с ней поздоровался: если пользователь сказал привет. Для большего интереса «привет» можно будет говорить на нескольких языках.
Заносим в set приветствия на разных языках.
Вводим с консоли слово,
если это слово есть в нашем множестве приветствий, то прощаемся (по-белорусски).
3. Множество
Коллекция Set создана для хранения множества элементов. Поэтому ее так и называют Set (множество). У этой коллекции есть три особенности.
Операции над множеством
С множеством можно делать только три операции: добавлять элементы во множество, удалять элементы из множества и проверять, есть ли во множестве определенный элемент. Все.
Отсутствие порядка
У элементов этой коллекции нет номеров. Нельзя получить элемент по его индексу или записать значение в коллекцию по определенному индексу. Методов get() и set() у множества нет.
Уникальность элементов
Все элементы множества уникальны. В отличие от списка, в множестве один элемент может быть только раз. Объект или находится во множестве, или нет: третьего не дано. Нельзя во «множество цветов» трижды добавить «черный цвет». Он там либо есть, либо его нет.
Поиск элементов
4. Сравнение коллекций: List vs Set
Давайте попробуем сравнить Список и Множество на примере детских игрушек.
Коллекция List (Список) похожа на набор игрушек в детской комнате, стоящих возле стены. Можно добавить игрушку в конец списка. Можно вставить и в середину, если очень нужно (но часть игрушек придется передвинуть).
У каждой игрушки есть порядковый номер. Можно взять игрушку по ее номеру или заменить игрушку номер 7 на игрушку номер 13. Можно удалить из списка игрушку номер 4. Ну и наконец, можно узнать количество всех игрушек в списке.
Коллекция Set (Множество) больше похожа на игрушки, сброшенные в кучу. В кучу можно добавить игрушку, можно удалить игрушку из кучи. Но фиксированного номера у таких игрушек нет.
Или допустим, вы выбираете ребенку игрушку на день рождения. Тогда вы в первую очередь думаете, есть у него такая игрушка или нет. Тогда все игрушки, которые у него есть, образуют множество игрушек, которые вы решили не покупать.
С этой точки зрения порядок игрушек в наборе «уже есть» не играет роли, как и наличие у именинника двух одинаковых игрушек. Вас интересуют не сами игрушки и их количество, а игрушки как набор неких уникальных объектов.