Понятие set на языке Java
Массивы в языке Java обладают фиксированной длиной. Каким бы способом не объявлялся массив, его длина всегда будет фиксирована. К примеру, мы объявили массив из 4-х элементов. Пятый элемент добавить нельзя, так как это приведет к ошибке. Такие ограничения могут вызывать сложности при написании программ. Однако есть альтернативный вариант — это множества(Set).
Удобнее хранить объекты в коллекции. В Java видов коллекций много, но все они расширяют возможности обычных массивов и обладают своими отдельными методами для манипуляций с данными.
Set (множества) — один из способов организации коллекций. В Java множества представляют собой интерфейс. Наследуются Set от интерфейса Collection(основного для всех множеств). Множества обладают неограниченной длиной. Это позволяет динамически(в ходе выполнения программы) изменять длину множества. К примеру, если коллекция состоит из 10 элементов, то свободно можно добавить и 11-й элемент или удалить 10-й.
Интерфейс Set, а также sortedSet являются наследниками главного интерфейса всех коллекций Collection. Set и sortedSet расширяют функционал Collection.
Интерфейс Collection реализует абстрактный класс для коллекций AbstractCollection. Этот класс имеет множество наследников и для множеств определен абстрактный класс-наследник AbstractSet. Интерфейсы и абстрактные классы Set, sortedSet, AbstractSet реализуют классы для создания объектов множеств. Для множеств определены следующие классы:
- HashSet. Объекты во множестве индексируются ключами — хэш-тегами.
- TreeSet. Множество отсортированных объектов в виде дерева.
- LinkedHashSet. Связанные между объекты в множестве.
Обобщенный класс HashSet
HashSet представляет собой хэш-таблицу. Объекты множества данного класса реализуют функционал интерфейса Set, а также AbstractSet. Таблица представляет собой набор объектов, где каждый объект обладает уникальным хэш-тегом(ключом). Ключ позволяет присвоить каждому объекту множества уникальный идентификатор. В классе реализуются только родительские методы и отсутствуют индивидуальные.
Синтаксис реализации объекта HashSet имеет следующую структуру:
HashSet<T> variable = new HashSet<T>() — пустое множество
Объекты множеств HashSet обладают следующими методами из интерфейса Collection:
- add(obj) — добавляет в множество объект(obj), который может быть либо того типа, который указан в обобщении, либо произвольного, если не указано обобщение. Возвращает true если нет такого объекта в множестве, в противном случае false.
- clear() — удаление всех объектов множества.
- contains(Object obj) — вернет true, если в множестве или коллекции содержится объект obj.
- isEmpty() — проверяет пуста ли коллекция, возвращает true или false.
- remove(Object obj) — если указанный объект удален удачно, то возвращает true.
- removeAll (Collection<T> collection) — удаление всех объектов из коллекции collection. Возвращает true при удалении хоть одного объекта.
- size() — число объектов коллекции по типу integer.
- toArray() — перевод коллекции в массив и его возврат.
Данные методы реализуются всеми коллекциями. Методы содержатся в интерфейсе Collection. Все абстрактные классы и объекты множеств и других коллекций наследуют данные методы. В целом, все коллекции отличаются друг от друга лишь способом хранения данных, а также тем, как они изменяются после добавления или удаления элементов.
Также у каждой коллекции разный метод индексирования и идентификации элементов. Другими словами — они по разному работают с памятью, но функционал их в основном аналогичен.
Интерфейс SortedSet
Множество SortedSet предназначено для хранения элементов в отсортированном виде по возрастанию. Данное множество хранит только уникальные элементы. Элементы сортируются по числу, занимаемой памяти, количеству элементов если это массив или строка.
Множества данного интерфейса обладают следующими индивидуальными функциями:
- first() — возвращает первый элемент множества;
- last() — возвращает последний элемент множества;
- headSet(end) — возвращает все элементы множества до элемента end;
- tailSet(start) возвращает все элементы множества, начиная с элемента start;
- subSet(start, end) — возвращает все элементы между start и end.
Синтаксис создания объекта SortedSet:
SortedSet<string> variable = new SortedSet<string>(); // для строковых объектов, но мжно для любых, в зависимости от <T>.
Пример:
SortedSet<integer> set_int = new SortedSet<integer>();
set_int.add(5);
set_int.add(2);
set_int.size(); // 2
set_int.remove(2);
set_int.size(); // 1
Обобщенный класс TreeSet
Структура данных в этом множестве представляется в виде дерева. Здесь объекты хранятся в отсортированной последовательности по возрастанию — по размеру памяти или старшинству элемента. Данный класс поддерживает все стандартные методы Collection.
Пример:
TreeSet<String> vegetables = new TreeSet<String>();
// добавим в множество несколько названий овощей
vegetables.add(«potatoes»);
vegetables.add(«tomato»);
vegetables.add(«cabbage»);
vegetables.add(«carrot»);System.out.printf(«Here is», states.size(), «groups of vegetables»);
// удаляем один из элементов
vegetables.remove(«carrot»);
vegetables.size(); // 3
// Если вывести все элементы дерева через цикл, то мы получим отсортированное множество элементов по алфавиту: cabbage->carrot->potato->tomato.
В целом, TreeSet реализует такие интерфейсы как NavigableSet и SortedSet, поэтому множества данного класса получают всю функциональность этих интерфейсов, плюс Collection.
Интерфейс NavigableSet
Данный интерфейс является расширением SortedSet. Множества данного интерфейса обладают следующими индивидуальными методами:
- ceiling(obj) — ищет элемент, который по структуре меньше, чем obj и возвращает его;
- floor(obj) — то же, что и предыдущий, только элемент наибольший и больше, чем obj;
- higher(obj) — аналог ceiling;
- lower(obj) — аналог floor;
- pollFirst() — возвращение первого элемента и удаление его из множества;
- pollLast() — аналогично предыдущему, только удаляется последний элемент;
- descendingSet() — возвращается множество NavigableSet, только элементы расположены в обратном порядке;
Пример:
NavigableSet<String> fruits = new NavigableSet<String>();
// добавим в множество несколько названий овощей
fruits.add(«banana»);
fruits.add(«pineaple»);
fruits.add(«apple»);
fruits.add(«orange»);System.out.printf(«Some of», states.size(), «groups of fruits»);
// удаляем один из элементов
fruits.remove(«apple»);
fruits.size(); // 3
for(int x : fruits ){system.out.print(x)} // banana, orange, pineaplefruits.last(); // orange
NavigableSet<String> back_fruits = fruits.descendingSet();
for(int x : back_fruits ){system.out.print(x)} // pineaple, orange, banana
Метод Iterator для множеств
Данный метод принадлежит интерфейсу Collection. Он возвращает объект Iterrator. У него есть свои индивидуальные методы, такие как next(), hasNext(), nextIndex().
Пример:
TreeSet<String> movies = new TreeSet<String>();
movies.add(«Commando»);
movies.add(«Harry Potter»);
movies.add(«Spiderman»);
movies.add(«Batman»);Iterator<String> SetIterator = movies.iterator();
while(iter.hasNext()){ // Пока в итераторе есть следующий элементSystem.out.println(iter.next()); // Commando, Harry Potter, Spiderman, Batman
Итератор удобно использовать в том случае, если множество или коллекцию часто придется перебирать циклами. Особые методы итератора упрощают работу с коллекцией.
Итог
Множества — это удобный способ хранения уникальных объектов. Множества не имеют ограничений по размеру. Инициализация не требует указания фиксированного размера памяти. Списки можно так выразиться «резиновые» — можно динамически добавлять элементы до бесконечности. Если говорить о всех типах списков, то они лишь по-разному распределяют элементы в памяти:
- упорядоченное хранение,
- неупорядоченное,
- элементы обобщенные или произвольные.
Однако стоит отметить, что все множества и коллекции в целом, используют одни и те же методы. Множества(Set) и другие типы коллекций обладают собой структурой, отличимой от массивов. Иногда это становится нужным в определенных условиях. Но за частую, коллекции лишь предоставляют удобный способ организации и хранения отдельных объектов.