如何在没有迭代器的情况下迭代Set/HashSet?

use*_*988 264 java loops set hashset

如何迭代Set/ HashSet没有以下内容?

Iterator iter = set.iterator();
while (iter.hasNext()) {
    System.out.println(iter.next());
}
Run Code Online (Sandbox Code Playgroud)

ass*_*ias 469

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

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

//populate set

for (String s : set) {
    System.out.println(s);
}
Run Code Online (Sandbox Code Playgroud)

或者使用Java 8:

set.forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

  • 我相信这在幕后使用了一个迭代器. (62认同)
  • @ user1621988有什么问题?我提供的代码没有问题.它只是提供了一种漂亮而干净的迭代方法,而无需显式使用迭代器. (36认同)
  • @munyengm是的.除了通过反射访问保存数据的底层结构,并复制Set#iterator提供的代码之外,没有办法迭代没有迭代器的集合. (18认同)

Ben*_*uer 84

至少有六种方法可以迭代一组.以下是我所知道的:

方法1

// Obsolete Collection
Enumeration e = new Vector(movies).elements();
while (e.hasMoreElements()) {
  System.out.println(e.nextElement());
}
Run Code Online (Sandbox Code Playgroud)

方法2

for (String movie : movies) {
  System.out.println(movie);
}
Run Code Online (Sandbox Code Playgroud)

方法3

String[] movieArray = movies.toArray(new String[movies.size()]);
for (int i = 0; i < movieArray.length; i++) {
  System.out.println(movieArray[i]);
}
Run Code Online (Sandbox Code Playgroud)

方法4

// Supported in Java 8 and above
movies.stream().forEach((movie) -> {
  System.out.println(movie);
});
Run Code Online (Sandbox Code Playgroud)

方法5

// Supported in Java 8 and above
movies.stream().forEach(movie -> System.out.println(movie));
Run Code Online (Sandbox Code Playgroud)

方法6

// Supported in Java 8 and above
movies.stream().forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

这是HashSet我用于我的例子:

Set<String> movies = new HashSet<>();
movies.add("Avatar");
movies.add("The Lord of the Rings");
movies.add("Titanic");
Run Code Online (Sandbox Code Playgroud)

  • 嗨@ benny-neugebauer对于**方法4**,**方法5**,**方法6**你可以简单地删除多余的`stream()`. (10认同)
  • 更不用说方法4,方法5和方法6相同。 (5认同)

Juv*_*nis 22

将您的集转换为数组 也可以帮助您迭代元素:

Object[] array = set.toArray();

for(int i=0; i<array.length; i++)
   Object o = array[i];
Run Code Online (Sandbox Code Playgroud)

  • 只是为了记录,`toArray`调用set的迭代器. (43认同)

Tha*_*hna 11

要演示,请考虑以下集合,它包含不同的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));
Run Code Online (Sandbox Code Playgroud)

人模型类

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

}
Run Code Online (Sandbox Code Playgroud)
  1. for语句有一个用于迭代集合和数组的表单.这种形式有时被称为增强for语句,可用于使循环更紧凑和易于阅读.
for(Person p:people){
  System.out.println(p.getName());
}
Run Code Online (Sandbox Code Playgroud)
  1. Java 8 - java.lang.Iterable.forEach(Consumer)
people.forEach(p -> System.out.println(p.getName()));
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)


Pri*_*jee 11

以下是有关如何迭代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);
    }
}
Run Code Online (Sandbox Code Playgroud)

代码是自我解释的.

持续时间的结果是:

Iterator Duration: 495287
Lambda Duration: 50207470
Stream Api:       2427392
Split Iterator:    567294
Run Code Online (Sandbox Code Playgroud)

我们可以看到Lambda最长的时间Iterator是最快的.


Sam*_*hie 11

您可以使用功能操作来获得更整洁的代码

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

set.forEach((s) -> {
     System.out.println(s);
});
Run Code Online (Sandbox Code Playgroud)