Java集合系列 Iterable、Iterator这俩兄弟细致解读(超通俗易懂)

Java集合系列 Iterable、Iterator这俩兄弟细致解读(超通俗易懂)Iterable 接口是为了达到实现该接口的类 可以使用 foreach 循环的目的

大家好,欢迎来到IT知识分享网。

一、Iterable接口是什么?

首先关注下图,这是Java集合架构层级,我们能发现其中Iterable接口是中最顶端的那一个。
在这里插入图片描述

打开Collection接口源码,能够看到Collection接口是继承了Iterable接口。

public interface Collection<E> extends Iterable<E> { 
    / * ...... */ } 

以下是Iterable接口源码及注释

/ * Implementing this interface allows an object to be the target of the "for-each loop" statement. * 实现这个接口允许一个对象成为for-each循环语句的目标 */ public interface Iterable<T> { 
    // 返回一个内部元素为T类型的迭代器(JDK1.5只有这个接口) Iterator<T> iterator(); // 遍历内部元素,action意思为动作,指可以对每个元素进行操作(JDK1.8添加) default void forEach(Consumer<? super T> action) { 
    Objects.requireNonNull(action); for (T t : this) { 
    action.accept(t); } } // 创建并返回一个可分割迭代器(JDK1.8添加),分割的迭代器主要是提供可以并行遍历元素的迭代器,可以适应现在cpu多核的能力,加快速度。 //(划重点:并行遍历元素 并行!) default Spliterator<T> spliterator() { 
    return Spliterators.spliteratorUnknownSize(iterator(), 0); } } 

划重点:实现这个接口 允许一个对象成为for-each循环语句的目标(大白话:实现此接口,能用foreach语句循环遍历)

Iterable接口定义了三个方法,其中两个提供了默认实现,只有iterator()是要求实现类必须实现的方法。
那么当某个类实现了Iterable接口就可以使用foreach进行迭代。同时Iterable中又封装了Iterator接口,那么这个类也可以使用Iterator迭代器。
因而有三种方式可以迭代Iterable实现类的对象:
1、for-each循环

List<String> list = new ArrayList><(); list.add("AAA"); list.add("BBB"); list.add("CCC"); for( String element : list ){ 
    System.out.println( element.toString() ); } 

2、获取Iterable实现类对象的迭代器(Iterator)

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

3、调用IterableforEach()方法

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

注:default修饰符,这也是Java8后新出现的。当给一个接口新添加一个方法,那么所有他的具体子类都必须实现此方法。为了能给接口拓展新功能,而又不必每个子类都要实现此方法,因此Java8新加了default关键字,被其修饰的方法可以不必由子类实现,并且由dafault修饰的方法在接口中有方法体,这打破了Java之前对接口方法的规范。

个人拙见:我们并不用过分在意这些方法的含义是什么,重点是需要记清楚,只要是实现了Iterable接口的对象,就都可以使用以上三种方式进行循环遍历

二、Iterator又是什么?

虽然在架构层级中并未包含,Iterator接口(迭代器)也是集合大家庭中的一员。Iterator主要是为了方便遍历集合中的所有元素(相当于是定义了遍历元素的范式)。

public interface Iterator<E> { 
    // 是否有下一个元素 boolean hasNext(); // 获取下一个元素 E next(); // 移除元素 default void remove() { 
    throw new UnsupportedOperationException("remove"); } // 对剩下的所有元素进行处理,action则为处理的动作,意为要怎么处理 default void forEachRemaining(Consumer<? super E> action) { 
    Objects.requireNonNull(action); while (hasNext()) action.accept(next()); } } 

注意:同样Iterator也是一个接口,目的是在于把不同集合的遍历方式抽象出来,这样我们使用迭代器遍历的时候,就不需要关注于集合内部结构,能够使用Iterator的内部方法直接遍历(也就是说,不管是针对List还是Set的遍历,我们都能够直接使用Iterator遍历拿到集合元素,而不需要关心是List还是Set)。那么这个时候,如果使用的数据结构有所变化,我们不需要去维护原有遍历集合的代码,因此也可以理解Iterator是有将集合与集合的遍历做了一个解耦

使用案例:

public static void main(String[] args) { 
    List<String> list = new ArrayList<String>(); list.add("张三1"); list.add("张三2"); list.add("张三3"); list.add("张三4"); List<String> linkList = new LinkedList<String>(); linkList.add("link1"); linkList.add("link2"); linkList.add("link3"); linkList.add("link4"); Set<String> set = new HashSet<String>(); set.add("set1"); set.add("set2"); set.add("set3"); set.add("set4"); //1.使用迭代器遍历ArrayList集合 Iterator<String> listIt = list.iterator(); while(listIt.hasNext()){ 
    System.out.println(listIt.next()); } //2.使用迭代器遍历Set集合 Iterator<String> setIt = set.iterator(); while(setIt.hasNext()){ 
    System.out.println(listIt.next()); } //3.使用迭代器遍历LinkedList集合 Iterator<String> linkIt = linkList.iterator(); while(linkIt.hasNext()){ 
    System.out.println(listIt.next()); } } 

三、Iterable Iterator两兄弟的区别

Iterable接口是为了达到实现该接口的类,可以使用foreach循环的目的。
Iterator接口是基于迭代器模式,实现了对聚合类的存储和遍历的分离
两者所强调的内容不同:

  • Iterable接口强调的是实现Iterable接口可使用foreach语法遍历,也可以使用迭代器遍历。
  • Iterator接口强调其实现类可使用迭代器遍历

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/144619.html

(0)
上一篇 2025-04-25 16:20
下一篇 2025-04-25 16:26

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信