关闭

Iterable接口和Iterator迭代器

标签: IterableIterator
443人阅读 评论(0) 收藏 举报
分类:

iterator接口定义如下

public interface Iterator<E> {

    boolean hasNext();
    E next();
    void remove();
}
该接口仅仅包含了三个函数,hasNext()和next()方法在我们常用的集合遍历中出现。 
三个函数的作用:
使用next()获得序列中的下一个元素。
使用hasNext()检查序列中是否还有元素。
使用remove()将迭代器新返回的元素删除。remove()方法必须和next方法一起使用。

对于已经实现了iterator接口的集合,一般遍历集合的写法为 如,我们常用的list集合,list集合已经实现了iterator接口 :
方法一:

list l = new ArrayList();
 l.add("aa");
 l.add("bb");
 l.add("cc");

  for (Iterator iter = l.iterator(); iter.hasNext();) {
  String str = (String)iter.next();
  System.out.println(str);
 }

方法二:

Iterator iter = l.iterator();
 while(iter.hasNext()){
  String str = (String) iter.next();
  System.out.println(str);
 }
这里我们查看 Abstractlist源码,中间有关于iterator实现细节,上面的iter实际上是多态,调用的其实是list的抽象Abstractlist类中的iterator方法:
private class Itr implements Iterator<E> {

        int cursor = 0;
        int lastRet = -1;
        int expectedModCount = modCount;

        public boolean hasNext() {
            return cursor != size();
        }

        public E next() {
            checkForComodification();
            try {
                int i = cursor;
                E next = get(i);
                lastRet = i;
                cursor = i + 1;
                return next;
            } catch (IndexOutOfBoundsException e) {
                checkForComodification();
                throw new NoSuchElementException();
            }
        }

        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                AbstractList.this.remove(lastRet);
                if (lastRet < cursor)
                    cursor--;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException e) {
                throw new ConcurrentModificationException();
            }
        }

        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }
通过源码,我们可以更加清晰的看出iterator三个函数的实现机制,细心的读者可能会发现,move()方法中 expectedModCount = modCount;有这样一个表达式。这其实是list中的快速失败机制。modcount在arraylist中的增删会使得其值变化,而expectedModcount是在遍历中维持的值,如果这两者不相等,表示在遍历的时候,出现了写操作。导致了数据不一致。 

Iterable接口定义如下

public interface Iterable<T> {

    /**
     * Returns an iterator over a set of elements of type T.
     *
     * @return an Iterator.
     */
    Iterator<T> iterator();
}
Java SE5引入了Iterable接口,该接口包含一个能够产生Iterator的iterator()方法,并且Iterable接口被foreach用来在序列中移动。因此你创建了任何实现Iterable的自定义类,都可以将它用于foreach语句中。
Iterable的主要作用为:实现Iterable接口来实现适用于foreach遍历的自定义类。
import java.util.Iterator;

public class IterablerClass<T> implements Iterable<T>{
    private T[] array = null;

    public IterablerClass(T[] t){
        this.array = t ;
    }
    @Override
    public Iterator<T> iterator() {
        // TODO Auto-generated method stub
        return new Iterator<T>() {
            private Integer index = 0;
            @Override
            public boolean hasNext() {
                // TODO Auto-generated method stub
                return index<array.length;
            }

            @Override
            public T next() {
                // TODO Auto-generated method stub
                return array[index++];
            }

            @Override
            public void remove() {
                // TODO Auto-generated method stub
            }
        };
    }
public static void main(String[] args) {
IterablerClass<String> iterablerClass = new IterablerClass<String>(new String[]{"hello","world","today","happy","sorrow"});
    for(String s:iterablerClass){
            System.out.print(s+" ");
        }

    }
}
用Iterator模式实现遍历集合 
        Iterator模式是用于遍历集合类的标准访问方法。它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免向客户端暴露集合的内部结构。
        例如,如果没有使用Iterator,遍历一个数组的方法是使用索引: for(int i=0; i<array.size(); i++) { ... get(i) ... }
        而访问一个链表(LinkedList)又必须使用while循环: while((e=e.next())!=null) { ... e.data() ... } 
        以上两种方法客户端都必须事先知道集合的内部结构,访问代码和集合本身是紧耦合,无法将访问逻辑从集合类和客户端代码中分离出来,每一种集合对应一种遍历方法,客户端代码无法复用。
        更恐怖的是,如果以后需要把ArrayList更换为LinkedList,则原来的客户端代码必须全部重写。
        解决以上问题,Iterator模式总是用同一种逻辑来遍历集合: for(Iterator it = c.iterater(); it.hasNext(); ) { ... } 
为什么一定要去实现Iterable这个接口呢?为什么不直接实现Iterator接口呢?
        看一下JDK中的集合类,比如List一族或者Set一族,都是实现了Iterable接口,但并不直接实现Iterator接口。 仔细想一下这么做是有道理的。
        因为Iterator接口的核心方法next()或者hasNext() 是依赖于迭代器的当前迭代位置的。 如果Collection直接实现Iterator接口,势必导致集合对象中包含当前迭代位置的数据(指针)。 当集合在不同方法间被传递时,由于当前迭代位置不可预置,那么next()方法的结果会变成不可预知。 除非再为Iterator接口添加一个reset()方法,用来重置当前迭代位置。 但即时这样,Collection也只能同时存在一个当前迭代位置。 而Iterable则不然,每次调用都会返回一个从头开始计数的迭代器。 多个迭代器是互不干扰的。

0
0
查看评论

java迭代器--Iterator和Iterable接口

java中有很多集合类型,不同的集合类型有不同的接口和实现。为了提供统一的操作接口,java提供了Iterator接口。本文主要介绍了java的迭代器,Iterator接口和foreach循环的Iterable接口。以及如何使用两者遍历和删除list和set集合的元素。
  • shuanghujushi
  • shuanghujushi
  • 2016-05-29 11:47
  • 1685

[java学习笔记]Iterator和Iterable接口

Iterator和Iterable都是java的迭代器接口,二者既有区别又有联系,下面从接口定义,接口调用和实际应用三方面具体分析这两个接口。
  • ciefer
  • ciefer
  • 2016-09-20 17:07
  • 321

iterator与iterable接口之间的区别

iterable接口最重要的方法是 Iterator<T> iterator(); //返回一个迭代器Iterator,而Iterator也是一个接口所以有很大的自由,Iterator接口最重要的方法是:以前三个最重要对任何一个集合实例都可以用这三个方法进行遍历所有元素。 ...
  • JQ_AK47
  • JQ_AK47
  • 2016-09-07 11:08
  • 1189

[scala--基础]--iterators类操作

Iterators 迭代器不是一个容器,更确切的说是逐一访问容器内元素的方法。迭代器it的两个基本操作是next和hasNext。调用it.next()会返回迭代器的下一个元素,并且更新迭代器的状态。在同一个迭代器上再次调用next,会产生一个新元素来覆盖之前返回的元素。如果没有元...
  • high2011
  • high2011
  • 2016-08-14 10:52
  • 2353

java中的Iterator和Iterable 区别 ,以及为么要有iterable接口

java.lang.Iterable java.util.Iterator 来自百度知道: Iterator是迭代器类(其实在javaAPI中其也是一个接口),而Iterable是接口。 好多类都实现了Iterable接口,这样对象就可以调用iterator()方法(返回一个It...
  • ningguixin
  • ningguixin
  • 2012-10-16 22:48
  • 3849

【Python】迭代器(iterator) vs 生成器(generator)

对python中的迭代器(iterator) vs 生成器(generator)之间的区别和应用进行介绍。
  • s120922718
  • s120922718
  • 2015-04-13 16:03
  • 5854

集合(Collection)与迭代器(Iterator)

集合(Collection)与迭代器(Iterator)这个大家都应该是不陌生了,我本来想介绍一下,不过,我想了一下,我说的,绝对没有《Think In Java》说的好,所以我就引用下面的话,然后,我举例测试,并附代码于后。  测试用例:import java.util.Arr...
  • fenglibing
  • fenglibing
  • 2007-08-20 23:26
  • 16328

java中Iterator和Iterable的区别

Iterator和Iterable都是接口。  好多类都实现了Iterable接口,这样对象就可以调用iterator()方法。  一般都是结合着用,比如  HashMap类就实现了Iterable接口,而要访问或打印出Map中所有内容时,就可以这样:HashMap h...
  • UP19910522
  • UP19910522
  • 2015-10-27 21:34
  • 2697

Java中Iterator与Iterable的区别

Iterable的定义: java.lang包 /** * Implementing this interface allows an object to be the target of * the "foreach" statement. * * @param...
  • colin_yjz
  • colin_yjz
  • 2015-06-28 18:59
  • 2691

Java中Iterable和Iterator的辨析

本文主要对Iterable和Iterator两个接口进行深入学习。1、Iterable接口Iterable接口 (java.lang.Iterable) 是Java集合的顶级接口之一。我们首先看下这这个接口在JDK中的定义:package java.lang; public interface It...
  • lipengcn
  • lipengcn
  • 2016-06-17 16:11
  • 5989
    个人资料
    • 访问:259643次
    • 积分:3646
    • 等级:
    • 排名:第10610名
    • 原创:140篇
    • 转载:36篇
    • 译文:0篇
    • 评论:23条
    最新评论