Вы действительно пытаетесь избежать использования итератора или просто не хотите видеть его в своем исходном коде?
Джон Скит
2
Вы можете сделать код короче и чище, но вы должны использовать итератор. Есть ли причина, по которой вы хотите этого избежать?
Питер Лоури
5
Просто для справки и в качестве объяснения, почему следует избегать итератора: я сейчас сталкиваюсь с этой проблемой в игре для Android, написанной на Java. Прямо сейчас я использую HashSet для хранения слушателей, которые должны регулярно получать уведомления о событиях. Тем не менее, многократная итерация коллекций вызывает большую активность сборщика мусора, которая может обременять игровой цикл. И это не нужно в Java-игре. Я собираюсь переписать эти части.
Тигучи
12
@thecoshman Я говорю только с точки зрения разработки игр на Java, где вы хотите избежать GC во время регулярных обновлений состояния игры любой ценой. Итераторы являются только временно полезными объектами, поскольку вы не можете сбросить их до начала, поэтому они воссоздаются при каждом вызове метода итерации (см., Например, источник ArrayList.java). При использовании в игровом цикле для итерации объектов сцены и рассмотрения не менее 30 обновлений в секунду вы получите не менее 60 (сценарий обычно повторяется дважды за цикл) объектов-итераторов в секунду, ожидающих GC. Это имеет большое влияние на Android.
Тигучи
9
Возможно, следует выбрать более адекватную структуру данных в этом случае? Набор не предназначен для эффективной итерации. Почему бы не использовать ArrayList и перебирать его со стандартным циклом for? Дополнительные итераторы не создаются, доступ для чтения очень быстрый.
Я считаю, что это использует итератор за кулисами.
munyengm
22
@munyengm Да, это так. Невозможно выполнить итерацию по множеству без итератора, кроме доступа к базовой структуре, которая хранит данные посредством отражения, и репликации кода, предоставленного Set # iterator ...
assylias
1
Это работает, но если это может вызвать проблемы, то это не решение для меня. Я думаю, у меня нет выбора, я должен использовать Iterator. Спасибо за все в любом случае.
user1621988
39
@ user1621988 Какие проблемы? Нет проблем с кодом, который я предоставил. Это просто хороший и простой способ перебора набора без явного использования итератора.
assylias
90
Существует как минимум шесть дополнительных способов перебора набора. Мне известны следующие:
Способ 1
// Obsolete CollectionEnumeration e =newVector(movies).elements();while(e.hasMoreElements()){System.out.println(e.nextElement());}
Способ 2
for(String movie : movies){System.out.println(movie);}
Способ 3
String[] movieArray = movies.toArray(newString[movies.size()]);for(int i =0; i < movieArray.length; i++){System.out.println(movieArray[i]);}
Способ 4
// Supported in Java 8 and above
movies.stream().forEach((movie)->{System.out.println(movie);});
Способ 5
// Supported in Java 8 and above
movies.stream().forEach(movie ->System.out.println(movie));
Способ 6
// Supported in Java 8 and above
movies.stream().forEach(System.out::println);
Это то, HashSetчто я использовал для моих примеров:
Set<String> movies =newHashSet<>();
movies.add("Avatar");
movies.add("The Lord of the Rings");
movies.add("Titanic");
Оператор for имеет форму, предназначенную для итерации по коллекциям и массивам. Эту форму иногда называют расширенной инструкцией for, и ее можно использовать для того, чтобы сделать ваши циклы более компактными и удобными для чтения.
defaultvoid forEach(Consumer<?super T> action)Performs the given action for each element of the Iterable until all elements have been processed or the action throws an exception.Unless otherwise specified by the implementing class, actions are performed in the order of iteration (if an iteration order is specified).Exceptions thrown by the action are relayed to the caller.ImplementationRequirements:Thedefault implementation behaves as if:for(T t :this)
action.accept(t);Parameters: action -The action to be performed for each element
Throws:NullPointerException-if the specified action is nullSince:1.8
Однако для этого уже есть очень хорошие ответы. Вот мой ответ:
1. set.stream().forEach(System.out::println);// It simply uses stream to display set values2. set.forEach(System.out::println);// It uses Enhanced forEach to display set values
Кроме того, если этот набор имеет тип пользовательского класса, например, для клиента.
Ответы:
Вы можете использовать расширенный цикл for :
Или с Java 8:
источник
Существует как минимум шесть дополнительных способов перебора набора. Мне известны следующие:
Способ 1
Способ 2
Способ 3
Способ 4
Способ 5
Способ 6
Это то,
HashSet
что я использовал для моих примеров:источник
stream()
.Преобразование вашего набора в массив может также помочь вам для перебора элементов:
источник
toArray
вызывает итератор набора.Для демонстрации рассмотрим следующий набор, содержащий различные объекты Person:
источник
Вы можете использовать функциональную операцию для более аккуратного кода
источник
Вот несколько советов о том, как итерировать набор вместе с их выступлениями:
Код не требует пояснений.
Результатом продолжительности являются:
Мы видим, что
Lambda
дубли самые длинные, аIterator
самые быстрые.источник
Перечисление (?):
Другой способ (java.util.Collections.enumeration ()):
Java 8:
или
источник
Однако для этого уже есть очень хорошие ответы. Вот мой ответ:
Кроме того, если этот набор имеет тип пользовательского класса, например, для клиента.
// Класс клиента:
источник