迭代器模式

1.为什么要使用迭代器模式

通过ArrayList的get方法可以很容易的将集合中的每个元素遍历出来,但是如果要获取hastSet的元素就比较麻烦了,需要掌握链表,数组甚至红黑树的遍历方式,所以为了方便将hastSet的元素遍历出来,jdk提供了一种迭代器的形式,这种设计就是现在要说的迭代器模式。

2.定义

提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。

3.主要角色

3.1 抽象迭代器

定义访问和遍历聚合元素的接口,一般包含hasNext()和next()等方法

3.2 具体迭代器

用于访问和遍历聚合元素

3.3 抽象集合

定义增加,删除等操作集合元素的接口和创建迭代器的接口

3.4 具体集合

实现增加,删除等操作集合元素和创建迭代器的方法

4.场景

设计一个图集对象,要求正向播放图片

4.1 抽象迭代器

public interface Iterator<T> {
    /**
     * 是否有下一个元素
     * @return
     */
    boolean hasNext();

    /**
     * 下一个元素
     * @return
     */
    T next();

}

4.2 抽象集合

public interface IGallery {
    void add(Picture picture);
    void remove(Picture picture);
    Iterator<Picture> iterator();
}

@Data
@AllArgsConstructor
public class Picture {
    private String name;
}

4.3 具体集合

public class Gallery implements IGallery {
    private List<Picture> pictures;

    Gallery() {
        pictures = new ArrayList<>();
    }

    public void add(Picture picture) {
        pictures.add(picture);
    }

    public void remove(Picture picture) {
        pictures.remove(picture);
    }

    public Iterator<Picture> iterator() {
        Gallery gallery = new Gallery();
        // 创建快照,防止获取元素异常
        gallery.pictures = new ArrayList<>(this.pictures);
        return new ForwardIterator(gallery);
    }

    private class ForwardIterator implements Iterator<Picture> {
        private List<Picture> pictures;
        private int curPos; // 当前指针位置

        ForwardIterator(Gallery gallery) {
            pictures = gallery.pictures;
            curPos = -1;
        }

        @Override
        public boolean hasNext() {
            return curPos < pictures.size()-1;
        }


        @Override
        public Picture next() {
            return pictures.get(++curPos);
        }

    }
}

4.4 测试

public class TestGallery {

    public static void main(String[] args) {
        Gallery gallery = new Gallery();
        gallery.add(new Picture("picture1"));
        gallery.add(new Picture("picture2"));
        Iterator iterator = gallery.iterator();
        System.out.println("============向后遍历元素开始============");
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
        System.out.println("============向后遍历元素结束============");
    }
}

----------------------------console
第一个元素:Picture(name=picture1)
最后一个元素:Picture(name=picture2)
============向后遍历元素开始============
Picture(name=picture1)
Picture(name=picture2)
============向后遍历元素结束============
============向后遍历元素开始============
============向后遍历元素结束============

5.jdk自带迭代器

上面的Iterator类在jdk存在类似的类java.util.Iterator,我们可以将上面的Iterator替换为java.util.Iterator,代码也是可以正常运行的,而且还可以实现一个更神奇的功能。一般遍历集合都会使用foreach语句,比如:

for(Object ele : list){
   // .....
}

只要实现了java.lang.Iterable,这里的Gallery类也可以实现一样的效果。修改后的代码如下:

public class Gallery implements IGallery,Iterable<Picture> {
    private List<Picture> pictures;

    Gallery() {
        pictures = new ArrayList<>();
    }

    public void add(Picture picture) {
        pictures.add(picture);
    }

    public void remove(Picture picture) {
        pictures.remove(picture);
    }

    public Iterator<Picture> iterator() {
        Gallery gallery = new Gallery();
        gallery.pictures = new ArrayList<>(this.pictures);
        return new ForwardIterator(gallery);
    }

    private class ForwardIterator implements Iterator<Picture> {
        private List<Picture> pictures;
        private int curPos; // 当前指针位置

        ForwardIterator(Gallery gallery) {
            pictures = gallery.pictures;
            curPos = -1;
        }

        @Override
        public boolean hasNext() {
            return curPos < pictures.size()-1;
        }

        @Override
        public Picture next() {
            return pictures.get(++curPos);
        }
    }
}

测试代码:

public class TestGallery {

    public static void main(String[] args) {
        Gallery gallery = new Gallery();
        gallery.add(new Picture("picture1"));
        gallery.add(new Picture("picture2"));
        for(Picture picture : gallery){
            System.out.println(picture);
        }
    }
}

----------------------------console
Picture(name=picture1)
Picture(name=picture2)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值