Iterable 接口解析

Iterable<T> 接口解析

一、说明

源码中对 Iterable 的说明是这样的:Implementing this interface allows an object to be the target of the “for-each loop” statement. See For-each Loop(实现此接口允许对象成为“ for-each循环”语句的目标。 请参阅 《For-each Loop》

意思就是说:实现此接口的类可以使用增强 for 循环。简单的例子如下:

// 增强 for 循环代码
private static final void descForeachLoop() {
    List<Integer> list = Arrays.asList(1,2,3,4);
    for (Integer i : list) {
        System.out.println(i);
    }
}

// Java 会自动编译成如下代码
private static final void descForeachLoop() {
    List<Integer> list = Arrays.asList(1, 2, 3, 4);
    Iterator var1 = list.iterator();

    while(var1.hasNext()) {
        Integer i = (Integer)var1.next();
        System.out.println(i);
    }

}

具体的解释可以参考 《For-each Loop》

二、源码

public interface Iterable<T> {
    Iterator<T> iterator();
    default void forEach(Consumer<? super T> action) {...}
    default Spliterator<T> spliterator() {...}
}

三、方法解析

关于泛型的说明大家可以参考 《Java知识点总结(Java泛型)》 ,或者自行搜索,这边不做过多的说明。

iterator() 方法

该方法没有参数,返回一个能够遍历容器的迭代器 Iterator<T> 。

迭代及的作用就是对容器中的元素进行遍历。具体的 Iterator 解析会在后续的文章中进行分析(TODO Iterator<T> 源码解析),需要的人可以自行搜索或等待后续文章。

forEach(Consumer<? super T> action)
循环容器中的元素,并对每个元素进行 action 操作,容器中不能有空元素,否则或抛出 NullPointerException 指针异常。例子:

private static final void descForeach() {
    LinkedList<String> linkedList = new LinkedList<>();
    linkedList.add("dddd");
    linkedList.add("eeee");
    linkedList.forEach(System.out::println);
}

关于例子中的 Lambda 表达式,可以参考《Java 8 实战》 密码:u3ex56,或者加QQ群:247498058 索取。

spliterator()

spliterator 方法没有参数,返回一个 Spliterator<T> 对象,Spliterator接口是1.8新加的接口,字面意思可分割的迭代器,不同以往的iterator需要顺序迭代,Spliterator可以分割为若干个小的迭代器进行并行操作,既可以实现多线程操作提高效率,又可以避免普通迭代器的fail-fast机制所带来的异常。Spliterator可以配合1.8新加的Stream进行并行流的实现,大大提高处理效率。具体的 Spliterator 解析会在后续的文章中进行分析(TODO Spliterator<T> 源码解析),也可以参考《java源码品读(9)— Spliterator》

一个小例子:

private static final void descSpliterator() {
    List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
    Spliterator<Integer> spliterator = list.spliterator();
    Spliterator<Integer> integerSpliterator = spliterator.trySplit();
    Spliterator<Integer> integerSpliterator1 = integerSpliterator.trySplit();
    spliterator.forEachRemaining(new MyConsumer<>());
    System.out.println("--------------");
    integerSpliterator.forEachRemaining(new MyConsumer<>());
    System.out.println("--------------");
    integerSpliterator1.forEachRemaining(new MyConsumer<>());
    System.out.println("--------------");

    list.stream().parallel().forEach(new MyConsumer<>());
    System.out.println("--------------");
    list.stream().forEach(new MyConsumer<>());
}

private static class MyConsumer<T> implements Consumer<T> {

    @Override
    public void accept(T o) {
        try {
            Thread.sleep(1000);
            System.out.println(Thread.currentThread().getName() + "--" + o.toString());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

// 执行结果如下:
main--4
main--5
main--6
main--7
--------------
main--2
main--3
--------------
main--1
--------------
main--5
ForkJoinPool.commonPool-worker-1--2
ForkJoinPool.commonPool-worker-2--7
ForkJoinPool.commonPool-worker-3--1
ForkJoinPool.commonPool-worker-3--4
ForkJoinPool.commonPool-worker-2--6
ForkJoinPool.commonPool-worker-1--3
--------------
main--1
main--2
main--3
main--4
main--5
main--6
main--7

五、总结

该说的上面都已经说过了:

  • Iterable<T> 接口提供一个增强 for 循环的实现
  • 提供一个默认 forEach 方法迭代元素
  • 对多线程,多 CPU 并行支持

六、参考资料

《For-each Loop》

《Java知识点总结(Java泛型)》

《java源码品读(9)— Spliterator》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章