Java итерация по set

Интерфейс Java Set

Интерфейс Java Set, java.util.Set, представляет коллекцию объектов, где каждый объект уникален. Другими словами, один и тот же объект не может встречаться более одного раза в наборе. Интерфейс является стандартным и подтипом интерфейса Collection, что означает, что Set наследуется от Collection.

Вы можете добавить любой объект в набор. Если набор не типизирован с использованием Java Generics, то вы можете даже смешивать объекты разных типов (классов) в одном наборе. Однако в действительности смешивание объектов разных типов в одном наборе не часто выполняется.

Сравнение со списком

Интерфейсы Set и Java List очень похожи друг на друга и представляет собой набор элементов. Тем не менее, есть некоторые существенные различия. Эти различия отражены в методах, которые содержат интерфейсы Set и List.

  1. Первое различие состоит в том, что один и тот же элемент не может встречаться в наборе более одного раза. Это отличается от списка, где каждый элемент может встречаться более одного раза.
  2. Второе отличие состоит в том, что элементы в 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, не меняет этот порядок.

Читайте также:  Executing python in browser

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 позволяет ограничить типы объектов, которые вы можете вставить:

Читайте также:  Java кей хорстманн 11 издание pdf

Этот набор теперь может содержать только экземпляры 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).

Источник

Best way to iterate through a Set in Java

The situation is that i have to iterate over a set having size up to 5000 elements in it. Currently, i am using a normal for loop with iterator.

for (Iterator iterator = allValues.iterator(); iterator.hasNext();)

The issue is its taking too much time to iterate like 6-7 seconds and i have to call the same loop multiple times.

Are you sure that it is the iteration that is taking the time? 5000 elements should take next to nothing

I don’t use Java a lot, but in Python, I would expect iteration over a set of mere 5000 elements to be very fast, and only a minute fraction of 6-7 seconds. I can only presume it would be similary fast in Java, and probably a lot faster. I suspect it is whatever is going on in inside your loop, so what exactly does abstractVO.getAllListMetadataElems() do, for example?

1 Answer 1

public class IterateSet < public static void main(String[] args) < //example Set Setset = new HashSet<>(); set.add("Jack"); set.add("John"); set.add("Joe"); set.add("Josh"); long startTime = System.nanoTime(); long endTime = System.nanoTime(); //using iterator System.out.println("Using Iterator"); startTime = System.nanoTime(); Iterator setIterator = set.iterator(); while(setIterator.hasNext()) < System.out.println(setIterator.next()); >endTime = System.nanoTime(); long durationIterator = (endTime - startTime); //using lambda System.out.println("Using Lambda"); startTime = System.nanoTime(); set.forEach((s) -> System.out.println(s)); endTime = System.nanoTime(); long durationLambda = (endTime - startTime); //using Stream API System.out.println("Using Stream API"); startTime = System.nanoTime(); set.stream().forEach((s) -> System.out.println(s)); endTime = System.nanoTime(); long durationStreamAPI = (endTime - startTime); //using Split Iterator (not recommended) System.out.println("Using Split Iterator"); startTime = System.nanoTime(); Spliterator splitIterator = set.spliterator(); splitIterator.forEachRemaining((s) -> System.out.println(s)); endTime = System.nanoTime(); long durationSplitIterator = (endTime - startTime); //time calculations System.out.println("Iterator Duration:" + durationIterator); System.out.println("Lamda Duration:" + durationLambda); System.out.println("Stream API:" + durationStreamAPI); System.out.println("Split Iterator:"+ durationSplitIterator); > > 

The code is self explanatory. The result of the durations are:

Iterator Duration:495287 Lamda Duration:50207470 Stream API:2427392 Split Iterator:567294 

We can see the Lambda takes the longest while Iterator is the fastest. Apart from this there is the traditional age-old enhanced for loop.

Источник

Оцените статью