- Интерфейс Java Set
- Сравнение со списком
- Пример набора
- Установление реализации
- Добавить элемент в набор
- Перебор элементов набора
- Итерация множества с помощью итератора
- Итерация множества с использованием цикла For-Each
- С использованием API Java Stream
- Как удалить элементы
- Как удалить все элементы
- Как добавить все элементы из другой коллекции
- Как удалить все элементы из другой коллекции
- Как сохранить все элементы, присутствующие в другой коллекции
- Как установить размер
- Как проверить, пуст ли Set
- Как проверить, содержится ли элемент
- Универсальные
- Как конвертировать в список
- Unmodifiable Sets
Интерфейс Java Set
Интерфейс Java Set, java.util.Set, представляет коллекцию объектов, где каждый объект уникален. Другими словами, один и тот же объект не может встречаться более одного раза в наборе. Интерфейс является стандартным и подтипом интерфейса Collection, что означает, что Set наследуется от Collection.
Вы можете добавить любой объект в набор. Если набор не типизирован с использованием Java Generics, то вы можете даже смешивать объекты разных типов (классов) в одном наборе. Однако в действительности смешивание объектов разных типов в одном наборе не часто выполняется.
Сравнение со списком
Интерфейсы Set и Java List очень похожи друг на друга и представляет собой набор элементов. Тем не менее, есть некоторые существенные различия. Эти различия отражены в методах, которые содержат интерфейсы Set и List.
- Первое различие состоит в том, что один и тот же элемент не может встречаться в наборе более одного раза. Это отличается от списка, где каждый элемент может встречаться более одного раза.
- Второе отличие состоит в том, что элементы в Set не имеют гарантированного внутреннего порядка. Элементы в списке имеют внутренний порядок, и элементы могут быть повторены в этом порядке.
Пример набора
Вот первый простой пример:
Set setA = new HashSet(); String element = "element 1"; setA.add(element); System.out.println( setA.contains(element) );
В этом примере создается HashSet, который является одним из классов в API Java, которые реализуют интерфейс Set. Затем он добавляет строковый объект в набор и, наконец, проверяет, содержит ли набор только что добавленный элемент.
Установление реализации
Будучи подтипом Collection, все методы в интерфейсе Collection также доступны в интерфейсе Set.
Поскольку Set – это интерфейс, вам нужно создать конкретную реализацию, чтобы использовать его. Вы можете выбрать:
- java.util.EnumSet;
- java.util.HashSet;
- Jawakutilklaidaked ashset;
- java.util.TreeSet.
Каждая из этих реализаций Set ведет себя немного по-разному в отношении порядка элементов при итерации набора и времени (большая запись O), необходимого для вставки и доступа к элементам в наборах.
HashSet поддерживается HashMap. Он не дает никаких гарантий относительно последовательности элементов при их итерации.
LinkedHashSet отличается от HashSet тем, что гарантирует, что порядок элементов во время итерации совпадает с порядком их вставки в LinkedHashSet. Повторная вставка элемента, который уже находится в LinkedHashSet, не меняет этот порядок.
TreeSet также гарантирует порядок элементов при повторении, но он является порядком сортировки элементов. Другими словами, порядок, в котором элементы должны быть отсортированы, если вы использовали Collections.sort() для List или массива, содержащего эти элементы. Этот порядок определяется либо их естественным порядком(если они реализуют Comparable), либо конкретной реализацией Comparator.
Вот несколько примеров того, как создать экземпляр Set:
Set setA = new EnumSet(); Set setB = new HashSet(); Set setC = new LinkedHashSet(); Set setD = new TreeSet();
Добавить элемент в набор
Чтобы добавить элементы в Set, вы вызываете его метод add(). Этот метод унаследован от интерфейса Collection. Вот несколько примеров:
Set setA = new HashSet(); setA.add("element 1"); setA.add("element 2"); setA.add("element 3");
Три вызова add() добавляют экземпляр String к набору.
Перебор элементов набора
Есть два способа перебора элементов набора Java:
Обе эти опции описаны в следующих разделах.
При выполнении итерации элементов в Set порядок элементов зависит от того, какую реализацию вы используете.
Итерация множества с помощью итератора
Чтобы выполнить итерацию элементов набора с помощью итератора, сначала необходимо получить его из набора. Вы получаете Iterator из Set, вызывая метод iterator():
Iterator iterator = set.iterator(); while(iterator.hasNext()
Итерация множества с использованием цикла For-Each
Второй способ перебора элементов набора – использование цикла for-each. Вот как выглядит итерация элементов Set с использованием цикла for-each:
Интерфейс Set реализует интерфейс Java Iterable. Вот почему вы можете перебирать элементы набора, используя цикл for-each.
С использованием API Java Stream
Чтобы выполнить итерацию с помощью API-интерфейса Java Stream, необходимо создать поток из набора:
Set set = new HashSet(); set.add("one"); set.add("two"); set.add("three"); Stream stream = set.stream(); stream.forEach((element) -> < System.out.println(element); >);
Как удалить элементы
Используется метод remove(Object o):
Невозможно удалить объект на основе индекса в наборе, поскольку порядок элементов зависит от его реализации.
Как удалить все элементы
Как добавить все элементы из другой коллекции
Интерфейс List имеет метод addAll(), который добавляет все элементы из другой Collection (List или Set) в Set. В теории множеств это соответствует объединению множества и другой коллекции . Вот пример:
Set set = new HashSet(); set.add("one"); set.add("two"); set.add("three"); Set set2 = new HashSet(); set2.add("four"); set2.addAll(set);
После выполнения set2 будет содержать четыре элемента String, а также три элемента String: один, два и три из набора.
Как удалить все элементы из другой коллекции
Интерфейс Java Set имеет метод с именем removeAll(), который удаляет все элементы в наборе, также присутствующие в другой коллекции. В теории множеств это называется разницей между множеством и другой коллекцией . Вот пример:
Set set = new HashSet(); set.add("one"); set.add("two"); set.add("three"); Set set2 = new HashSet(); set2.add("three"); set.removeAll(set2);
После запуска набор будет содержать элементы String один и два. Третий элемент был удален, потому что он присутствовал в set2, который был задан как параметр для set.removeAll(set2).
Как сохранить все элементы, присутствующие в другой коллекции
Интерфейс Set также имеет метод, который сохраняет все элементы в наборе, также присутствующие в другой коллекции. Все найденные в наборе элементы, которых нет в другой коллекции, будут удалены. В теории множеств это называется пересечением между множеством и другой коллекцией . Вот пример:
Set set = new HashSet(); set.add("one"); set.add("two"); set.add("three"); Set set2 = new HashSet(); set2.add("three"); set2.add("four"); set.retainAll(set2);
После запуска набор будет содержать только элемент String три, так как присутствует как в set, так и в set2.
Как установить размер
Используется метод size(). Размер набора – это количество элементов, содержащихся в наборе. Вот пример чтения размера:
Set set = new HashSet(); set.add("123"); set.add("456"); set.add("789"); int size = set.size();
После выполнения переменная размера будет иметь значение 3, потому что созданный в примере набор имеет 3 добавленных элемента.
Как проверить, пуст ли Set
Используется метод isEmpty() для Set:
Set set = new HashSet(); boolean isEmpty = set.isEmpty();
После запуска этого кода переменная isEmpty будет содержать значение true, потому что Set пуст (в нем нет элементов).
Вы также можете проверить, является ли Set пустым, сравнив значение, возвращаемое методом size() с 0:
Set set = new HashSet(); boolean isEmpty =(set.size() == 0);
После выполнения этого кода переменная isEmpty будет содержать значение true, потому что метод Set size() возвращает 0 – в примере не содержится элементов.
Как проверить, содержится ли элемент
Вы можете проверить, содержит ли Set данный элемент (объект), вызвав метод contains():
Set set = new HashSet(); set.add("123"); set.add("456"); boolean contains123 = set.contains("123");
После выполнения этого кода переменная contains123 будет содержать значение true, потому что Set на самом деле содержит строку 123.
Чтобы определить, содержит ли набор элемент, он будет внутренне выполнять итерации своих элементов и сравнивать каждый с объектом, переданным в качестве параметра. Для сравнения используется метод равенства.
Поскольку можно добавить нулевые значения, также можно проверить, содержит ли набор нулевое значение:
set.add(null); containsElement = set.contains(null); System.out.println(containsElement);
Очевидно, что если входной параметр для contains() имеет значение null, метод contains() не будет использовать метод equals() для сравнения с каждым элементом, а вместо этого использует оператор ==.
Универсальные
По умолчанию вы можете поместить любой объект в набор, но с Java 5 Java Generics позволяет ограничить типы объектов, которые вы можете вставить:
Этот набор теперь может содержать только экземпляры MyObject. Затем вы можете получить доступ к элементам и выполнить итерацию без их приведения:
for(MyObject anObject : set) < //do someting to anObject. >
Как конвертировать в список
Вы можете преобразовать Set в List, создав List и вызвав его метод addAll(), передав Set в качестве параметра:
Set set = new HashSet(); set.add("123"); set.add("456"); List list = new ArrayList(); list.addAll(set);
После запуска этого примера список будет содержать строковые элементы 123 и 456 – так как это были все элементы, присутствующие в наборе при вызове List addAll(set).
Interface Set
A collection that contains no duplicate elements. More formally, sets contain no pair of elements e1 and e2 such that e1.equals(e2) , and at most one null element. As implied by its name, this interface models the mathematical set abstraction.
The Set interface places additional stipulations, beyond those inherited from the Collection interface, on the contracts of all constructors and on the contracts of the add , equals and hashCode methods. Declarations for other inherited methods are also included here for convenience. (The specifications accompanying these declarations have been tailored to the Set interface, but they do not contain any additional stipulations.)
The additional stipulation on constructors is, not surprisingly, that all constructors must create a set that contains no duplicate elements (as defined above).
Note: Great care must be exercised if mutable objects are used as set elements. The behavior of a set is not specified if the value of an object is changed in a manner that affects equals comparisons while the object is an element in the set. A special case of this prohibition is that it is not permissible for a set to contain itself as an element.
Some set implementations have restrictions on the elements that they may contain. For example, some implementations prohibit null elements, and some have restrictions on the types of their elements. Attempting to add an ineligible element throws an unchecked exception, typically NullPointerException or ClassCastException . Attempting to query the presence of an ineligible element may throw an exception, or it may simply return false; some implementations will exhibit the former behavior and some will exhibit the latter. More generally, attempting an operation on an ineligible element whose completion would not result in the insertion of an ineligible element into the set may throw an exception or it may succeed, at the option of the implementation. Such exceptions are marked as «optional» in the specification for this interface.
Unmodifiable Sets
- They are unmodifiable. Elements cannot be added or removed. Calling any mutator method on the Set will always cause UnsupportedOperationException to be thrown. However, if the contained elements are themselves mutable, this may cause the Set to behave inconsistently or its contents to appear to change.
- They disallow null elements. Attempts to create them with null elements result in NullPointerException .
- They are serializable if all elements are serializable.
- They reject duplicate elements at creation time. Duplicate elements passed to a static factory method result in IllegalArgumentException .
- The iteration order of set elements is unspecified and is subject to change.
- They are value-based. Programmers should treat instances that are equal as interchangeable and should not use them for synchronization, or unpredictable behavior may occur. For example, in a future release, synchronization may fail. Callers should make no assumptions about the identity of the returned instances. Factories are free to create new instances or reuse existing ones.
- They are serialized as specified on the Serialized Form page.
This interface is a member of the Java Collections Framework.