如何在没有Iterator的情况下迭代Set / HashSet?
我如何迭代一个Set
/ HashSet
没有以下?
Iterator iter = set.iterator(); while (iter.hasNext()) { System.out.println(iter.next()); }
您可以使用增强的for循环 :
Set<String> set = new HashSet<String>(); //populate set for (String s : set) { System.out.println(s); }
或者与Java 8:
set.forEach(System.out::println);
至less有六种方法可以迭代一组。 以下是我所知道的:
方法1
// Obsolete Collection Enumeration e = new Vector(movies).elements(); while (e.hasMoreElements()) { System.out.println(e.nextElement()); }
方法2
for (String movie : movies) { System.out.println(movie); }
方法3
String[] movieArray = movies.toArray(new String[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 = new HashSet<>(); movies.add("Avatar"); movies.add("The Lord of the Rings"); movies.add("Titanic");
将你的集合转换成一个数组也可以帮助你迭代元素:
Object[] array = set.toArray(); for(int i=0; i<array.length; i++) Object o = array[i];
为了演示,请考虑以下设置,它包含不同的Person对象:
Set<Person> people = new HashSet<Person>(); people.add(new Person("Tharindu", 10)); people.add(new Person("Martin", 20)); people.add(new Person("Fowler", 30));
人模型类
public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } //TODO - getters,setters ,overridden toString & compareTo methods }
- for语句有一个为集合和数组迭代而devise的表单。这种表单有时被称为enhanced for语句,可以用来使循环更加紧凑,易于阅读。
for(Person p:people){ System.out.println(p.getName()); }
- Java 8 – java.lang.Iterable.forEach(Consumer)
people.forEach(p -> System.out.println(p.getName()));
default void 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. Implementation Requirements: The default 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 null Since: 1.8
枚举(?):
Enumeration e = new Vector(set).elements(); while (e.hasMoreElements()) { System.out.println(e.nextElement()); }
另一种方式(java.util.Collections.enumeration()):
for (Enumeration e1 = Collections.enumeration(set); e1.hasMoreElements();) { System.out.println(e1.nextElement()); }
Java 8:
set.forEach(element -> System.out.println(element));
要么
set.stream().forEach((elem) -> { System.out.println(elem); });
以下是关于如何迭代Set以及它们的性能的一些技巧:
public class IterateSet { public static void main(String[] args) { //example Set Set<String> set = 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<String> 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<String> 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); } }
代码是自我解释的。
持续时间的结果是:
Iterator Duration:495287 Lamda Duration:50207470 Stream API:2427392 Split Iterator:567294
我们可以看到Lambda
需要最长的时间,而Iterator
是最快的。
你可以使用函数操作来获得更整洁的代码
Set<String> set = new HashSet<String>(); set.forEach((s) -> { System.out.println(s); });