谈谈Iterator

今天看了马老师的设计模式的视频,感觉收货很多。记得以前学习容器的时候,刚开始接触Iterator的时候,确实不明白这个东西是怎么回事,就只知道我想遍历容器的时候先while(it.hasNext),之后再用next()取出来,因为用着非常简单,就没想太深入的看看源码什么的,今天突然发现这东西其实挺厉害,能实现对不同容器的遍历,实现对单一容器的遍历并不难,但是能把所有容器遍历还是很厉害的。今天我就按照老师视频上的讲解跟大家分享下我的理解。
以最简单的Arraylist 为例:
首先先定义个Collection借口 ,只需要实现add(Object o) 和size()方法
![自己简单的定义了个Collection借口,与jdk 中不同](https://img-blog.csdn.net/20160903102224762)
接着定义个ArrayList
![这里写图片描述](https://img-blog.csdn.net/20160903102424187)
@Override
public int size() {
    return index;
}
为了对比在写个LinkedList 
package com.littlefive.ssm.test;

/**Created by littlefive on 2016-9-2 下午10:40:58
*/
public class LinkedList implements Collection {
private int size=0;
private Node head=null;
@Override
public void add(Object o){
Node node=new Node(o,null);
if(head==null){
head=node;
}else{
head.setNode(node);
head=node;
}
size++;

}
@Override
public int size(){
    return size;
}
最后测试类
package com.littlefive.ssm.test;

/**Created by littlefive on 2016-9-2 下午10:40:42
*/
import com.littlefive.ssm.test.ArrayList;
public class Test {

public static void main(String[] args) {
    Collection c=new ArrayList();
    for(int i=0;i<15;i++){
        c.add(new Object());
    }
    System.out.println(c.size());
}

}
这里如果我们要遍历的话,就要先把c 先转换成ArrayList 在用for() 或者for-each来写遍历,那如果我们是用的LinkedList 呢,所以这很麻烦
那我们怎么写才能不变遍历方式 把容器的内容遍历出来呢
这就意味着我们不同的集合都要提供一个相同的方法用来遍历集合 我们暂且叫它 iterator()
那么我们每个集合类需要提供什么呢
一个方法用来返回容器里存放的对象,Object next()
另一个方法用来判断还有没有下一个元素即可。boolean hasNext();
这样我们可以通过这俩个方法 遍历数组。接下来就是代码了
我们为了规范每个容器类 ,给他们定义一个借口,就叫Iterator
package com.littlefive.ssm.test;
/**Created by littlefive on 2016-9-3 上午10:42:02
*/
public interface Iterator {

public Object next();

public boolean hasNext();

}
之后我们就要为每个不容的容器写方法了
为了方便我们直接在Collection 中定义个方法,让每个容器类重写即可
package com.littlefive.ssm.test;
/**Created by littlefive on 2016-9-3 上午9:40:57
*/
public interface Collection {
public void add(Object o);
public int size();
public Iterator iterator();
}
以ArrayList 为例,

@Override
public Iterator iterator() {

    return null;
}

在ArrayList 中实现这个方法即可,那我们这个方法要返回一个实现了Iterator借口的实现类,在这个类中我们可以写我们上边说的要遍历所需要的俩个方法。ArrayList自己实现也可以,我们这里模仿jdk用一个内部类实现
@Override
public Iterator iterator() {

    return new ArrayListIterator();
}
class ArrayListIterator implements Iterator{

    //定义一个当前的索引
    public int cruentIndex=0;


    @Override
    public boolean hasNext() {
        if(cruentIndex>=index){
            return false;
        }else{
            return true;
        }
    }
    @Override
    public Object next() {
        Object o=objects[cruentIndex];
        cruentIndex++;
        return o;
    }
}
这样测试方法可以写:
    Iterator i=c.iterator();
    while(i.hasNext()){
        System.out.println(i.next());
    }

结果:
Product [id=0]
Product [id=1]
Product [id=2]
Product [id=3]
Product [id=4]
Product [id=5]
Product [id=6]
Product [id=7]
Product [id=8]
Product [id=9]
Product [id=10]
Product [id=11]
Product [id=12]
Product [id=13]
Product [id=14]

我现在有疑惑的地方是 为什么我们要间接的提供一个iterator()方法呢 直接让ArrayList 实现Iterator 借口 或者Collection 直接继承Iterator借口
这样直接就可以
public interface Collection extends Iterator{
public void add(E o);
public int size();
}

package com.littlefive.ssm.test;
/**Created by littlefive on 2016-9-3 上午9:42:55
*/
public class ArrayList implements Collection{
private Object [] objects=new Object[10];
private int index=0;
private int cruentIndex=0;
@Override
public void add(E o) {
if(index>=objects.length){
Object[] newObjects=new Object[objects.length*2];
System.arraycopy(objects, 0, newObjects, 0, objects.length);
objects=newObjects;
}
objects[index]=o;
index++;
}

@Override
public int size() {
    return index;
}




@Override
public boolean hasNext() {
    if(cruentIndex>=index){
        return false;
    }else{
        return true;
    }

}
@Override
public Object next() {
    Object o=objects[cruentIndex];
    cruentIndex++;
    return o;

}

}
package com.littlefive.ssm.test;
/**Created by littlefive on 2016-9-2 下午10:40:42
*/
import com.littlefive.ssm.test.ArrayList;
public class Test {

public static void main(String[] args) {
    Collection<Product> c=new ArrayList<Product>();
    for(int i=0;i<15;i++){
        c.add(new Product(i));
    }
    System.out.println(c.size());


    while(c.hasNext()){
        System.out.println(c.next());
    }
}

}
这样不是更方便吗?


猜你喜欢

转载自blog.csdn.net/wlittlefive/article/details/52422291