如何迭代一个集/HashSet没有迭代器?

我如何迭代一个Set/HashSet没有以下?

Iterator iter = set.iterator();
while (iter.hasNext()) {
System.out.println(iter.next());
}
826478 次浏览

你可以使用增强的for循环:

Set<String> set = new HashSet<String>();


//populate set


for (String s : set) {
System.out.println(s);
}

或者使用Java 8:

set.forEach(System.out::println);

将set转换为数组 也可以帮助你迭代元素:

Object[] array = set.toArray();


for(int i=0; i<array.length; i++)
Object o = array[i];

枚举(?):

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);
});

为了演示,考虑下面的集合,它包含不同的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


}
  1. for语句有一种设计用于通过集合和数组进行迭代的形式,这种形式有时被称为增强的for语句,可用于使循环更加紧凑和易于阅读。
for(Person p:people){
System.out.println(p.getName());
}
  1. Java 8 - Java .lang. iterable . foreach(消费者)
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

至少有六种方法可以遍历一个集合。我了解到以下情况:

方法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");

下面是一些关于如何迭代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
Lambda Duration: 50207470
Stream Api:       2427392
Split Iterator:    567294

我们可以看到Lambda耗时最长,而Iterator最快。

您可以使用函数式操作来获得更简洁的代码

Set<String> set = new HashSet<String>();


set.forEach((s) -> {
System.out.println(s);
});

然而,对于这个问题已经有了很好的答案。以下是我的回答:

1. set.stream().forEach(System.out::println); // It simply uses stream to display set values
2. set.forEach(System.out::println); // It uses Enhanced forEach to display set values

同样,如果这个集合是自定义类类型,例如:Customer。

Set<Customer> setCust = new HashSet<>();
Customer c1 = new Customer(1, "Hena", 20);
Customer c2 = new Customer(2, "Meena", 24);
Customer c3 = new Customer(3, "Rahul", 30);


setCust.add(c1);
setCust.add(c2);
setCust.add(c3);
setCust.forEach((k) -> System.out.println(k.getId()+" "+k.getName()+" "+k.getAge()));

//客户类:

class Customer{
private int id;
private String name;
private int age;


public Customer(int id,String name,int age){
this.id=id;
this.name=name;
this.age=age;
} // Getter, Setter methods are present.}