Java可迭代

时间:2020-01-09 10:35:47  来源:igfitidea点击:

Java Iterable接口表示对象的集合,这些对象具有可迭代的含义,可以迭代。这意味着,实现JavaIterable接口的类可以对其元素进行迭代。我们可以通过三种方式来迭代Java Iterable的对象:通过,通过从Iterable获取Java迭代器,或者通过调用Java IterableforEach()方法。在本Java Iterable教程的后面,我们将看到所有这三种迭代方法的示例。

使用for-each循环迭代一个Iterable

迭代Java Iterable元素的第一种方法是通过Java for-each循环循环。下面的示例显示了如何通过Java for-each循环迭代Java List的元素。由于Java的List接口扩展了Collection接口,而Collection接口扩展了Iterable接口,因此List对象可以与for-each循环一起使用。

List<String> list = new ArrayList><();

list.add("one");
list.add("two");
list.add("three");

for( String element : list ){
    System.out.println( element.toString() );
}

此示例首先创建一个新的"列表",并向其中添加3个元素。然后,它使用for-each循环来迭代List的元素,并打印出每个元素的toString()值。

通过迭代器迭代一个Iterable

迭代Java Iterable元素的第二种方法是通过调用Iterableiterator()方法从其中获得Java Iterator。然后,我们可以像使用其他任何迭代器一样迭代该迭代器。我们可以在Java Iterator教程中阅读有关Java Iterator的更多信息。这是一个迭代Java Iterable元素的示例(此示例中为Java List):

List<String> list = new ArrayList><();

list.add("one");
list.add("two");
list.add("three");

Iterator<String> iterator = list.iterator();

while(iterator.hasNext()) {
    String element = iterator.next();
    System.out.println( element );
}

通过其forEach()方法迭代Iterable

迭代Java Iterable元素的第三种方法是通过其forEach()方法。 forEach()方法采用Java Lambda表达式作为参数。对于Iterable中的每个元素,都会调用一次此lambda表达式。这是一个通过其forEach()方法迭代Iterable元素的示例:

List<String> list = new ArrayList><();

list.add("one");
list.add("two");
list.add("three");

list.forEach( (element) -> {
    System.out.println( element );
});

可迭代的接口定义

Java" Iterable"接口具有三种方法,其中仅一种方法需要实现。其他两个具有默认实现。这是Iterable接口的定义:

public interface Iterable<T> {

  Iterator<T>    iterator();

  Spliterator<T> spliterator();

  void           forEach(Consumer<? super T> action);

}

我们必须实现的方法名为iterator()。该方法必须返回一个Java迭代器,该迭代器可用于迭代实现Iterable接口的对象的元素。获取Iterator是在幕后进行的,因此我们看不到完成的事情。当在for-each循环中使用" Iterable"时,Java编译器会负责为此生成代码。

Java中Iterable的实现

Java Iterable接口(java.lang.Iterable)是Java Collections API的根接口之一。因此,Java中有几个实现Java"可迭代"接口的类。因此,可以对这些类的内部元素进行迭代。

还有几个Java接口扩展了Iterable接口。实现扩展Iterable接口的接口的类因此也实现Iterable接口。这样的类也可以迭代其元素。

"集合"接口扩展了"可迭代",因此"集合"的所有子类型也都实现了"可迭代"接口。例如,Java的List和Set接口都扩展了Collection接口,从而扩展了Iterable接口。

实现可迭代的接口

《 Java泛型》教程中的《实现可迭代接口》一文中介绍了如何实现此"可迭代"接口,以便可以将其与for-each循环一起使用。

在这里,我将仅向我们展示一个简单的Iterable实现示例:

public class Persons implements Iterable {
    private List<Person> persons = new ArrayList<Person>();    
    
    public Iterator<Person> iterator() {
        return this.persons.iterator();
    }
}

可以将" Persons"的一个实例与Java for-each循环一起使用,如下所示:

Persons persons = ... //obtain Persons instance with Person objects inside.

for(Person person : persons) {
    // do something with person object.
}

获取分离器

我们可以通过Java Iterable的spliterator()方法获取Java Spliterator。在这里,我不会进入Spliterator界面,只是展示如何从Iterable中获取Spliterator:

List<String> list = new ArrayList><();

list.add("one");
list.add("two");
list.add("three");

Spliterator<String> spliterator = list.spliterator();

可迭代的性能

如果我们正在编写一些需要在一个紧密循环中多次迭代集合的代码,那么可以说每秒对Java列表进行数千次迭代,通过Java for-each循环对List进行迭代比对列表进行迭代要慢通过一个标准的for循环,如下所示:(``)。

for(int i=0; i<list.size(); i++) {
    Object obj = list.get(i);
}

for-each循环较慢的原因是,每次迭代都会调用Listiterator()方法,这将创建一个新的Iterator对象。与仅使用标准的for循环迭代" List"相比,每秒创建数千个,甚至每秒数百万次的新对象确实会降低性能。

对于偶尔迭代收集的大多数标准业务应用程序,此性能差异无关紧要。仅对于每秒执行数千次的非常紧密的循环才有意义。