【java设计模式】(6)---迭代器模式(案例解析)

设计模式之迭代器模式

 

1、java迭代器介绍

一、迭代器接口

在jdk中,与迭代器相关的接口有两个:Iterator 与 Iterable。html

Iterator:迭代器,Iterator及其子类一般是迭代器自己的结构与方法;迭代器是一种模式,它可使得对于序列类型的数据结构的遍历行为与被遍历的对象分离,即咱们无需关心该序列的底层结构是什么样子的。只要拿到java

这个对象,使用迭代器就能够遍历这个对象的内部。设计模式

Iterable:可迭代的,那些想用到迭代器功能的其它类,如AbstractList HashMap等,须要实现该接口。 数据结构

1)Iteratorapp

      Java提供一个专门的迭代器<<interface>>Iterator,咱们能够对某个序列实现该interface,来提供标准的Java迭代器。Iterator接口实现后的功能是“使用”一个迭代器。ide

Package java.util; public interface Iterator<E> { //判断是否存在下一个对象元素 
    boolean hasNext(); //得到下一个元素
 E next(); //移除下一个元素
    void remove(); } 

 2)Iterable函数

       Java中还提供了一个Iterable接口,Iterable接口实现后的功能是“返回”一个迭代器(Iterator),咱们经常使用的实现了该接口的子接口有: Collection<E>, Deque<E>, List<E>, Queue<E>, Set<E> 等.该接口的iterator()方测试

法返回一个标准的Iterator实现。this

public interface Iterable<T> { Iterator<T> iterator(); } 

 二、迭代器的实现

看完源码,咱们来看看迭代器是如何使用的: spa

    1) 若类A想要使用迭代器,则它的类声明部分为 class A implement Iterable 

    2) 在类A实现中,要实现Iterable接口中的惟一方法:Iterator<T> iterator(); 这个方法用于返回一个迭代器,即Iterator接口及其子类; 

    3) 在类A中,定义一个内部类S,专门用于实现Iterator接口,定制类A自已的迭代器实现。

以下:

//A实现Iterable接口
class A implement Iterable { //该接口返回一个Iterator对象
    Iterator<T> iterator() {...} class S implement Iterator<E> { //上面这个对象会有具体实现的方法
        boolean hasNext() {....} E next() {....} void remove() {....} } }

下面咱们来看下抽象类AbstractList的jdk源码

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> { // List接口实现了Collection<E>, Iterable<E> 
   
   protected AbstractList() { } ... // 这里返回一个迭代器对象 
   public Iterator<E> iterator() { return new Itr(); } // Itr内部类实现迭代器 
    private class Itr implements Iterator<E> { int cursor = 0; int lastRet = -1; int expectedModCount = modCount; // 实现hasNext方法 
    public boolean hasNext() { return cursor != size(); } // 实现next方法 
    public E next() { //判断是否有下一个
 checkForComodification(); try { E next = get(cursor); lastRet = cursor++; //返回下一个 
        return next; } catch (IndexOutOfBoundsException e) { checkForComodification(); throw new NoSuchElementException(); } } // 实现remove方法 
    public void remove() { if (lastRet == -1) 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(); } } } 

三、小案例

//实现Iterable
class ScanAppleStore implements Iterable<String> { ArrayList<String> appleStore = new ArrayList<String>(); //为初始appleStore赋值
 ScanAppleStore() { Collections.addAll(appleStore, "Sweet", "Sour", "Bitter", "litter Sweet", "litter Sour", "litter Bitter"); System.out.print(appleStore); } //重写Iterator方法
 @Override public Iterator<String> iterator() { return new Iterator<String>() { private int i = 0; public boolean hasNext() { if (i < appleStore.size()) { return true; } else { return false; } } public String next() { return appleStore.get(i++); } public void remove() { System.out.print("not defined!"); } }; } public Iterable<String> reverseIterator() { return new Iterable<String>() { public Iterator<String> iterator() { return new Iterator<String>() { private int i = appleStore.size() - 1; public boolean hasNext() { if (i > -1) { return true; } else { return false; } } public String next() { return appleStore.get(i--); } public void remove() { System.out.print("not defined!"); } }; } }; }}

测试类

public class TestIterable { //构造函数初始化
 TestIterable() { ScanAppleStore appleTree = new ScanAppleStore(); //采用系统自带的迭代器
        System.out.println("采用系统自带的迭代器iterator:"); for (String str : appleTree) { System.out.println(str); } System.out.println("======================"); System.out.println("采用本身从新迭代器,让相反输出"); //采用本身从新迭代器,让相反输出
        for (String str : appleTree.reverseIterator()) { System.out.println(str); } } public  static void main(String[] args) { TestIterable a = new TestIterable(); } }

运行结果

[Sweet, Sour, Bitter, litter Sweet, litter Sour, litter Bitter]
采用系统自带迭代器iterator: Sweet Sour Bitter litter Sweet litter Sour litter Bitter
====================== 采用本身从新迭代器,让相反输出: litter Bitter litter Sour litter Sweet Bitter Sour Sweet

 

2、迭代器模式

一、什么是迭代器模式

   GOF给出的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。  

   Iterator模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既能够作到不暴露集合的内部结构,又可以让外部代码透明的访问集合内部的数据。

二、迭代器模式角色组成

       1) 迭代器角色(Iterator):迭代器角色负责定义访问和遍历元素的接口。 

  2) 具体迭代器角色(Concrete Iterator):具体迭代器角色要实现迭代器接口,并要记录遍历中的当前位置。 

       3) 容器角色(Container):容器角色负责提供建立具体迭代器角色的接口。 

    4) 具体容器角色(Concrete Container):具体容器角色实现建立具体迭代器角色的接口——这个具体迭代器角色于该容器的结构相关。 

三、案例解析

  1)迭代器角色

public interface Iterator { public Object next(); public boolean hasNext(); }

 2)具体迭代器角色

public class ConcreteIterator implements Iterator { private List list = new ArrayList(); private int cursor = 0; public ConcreteIterator(List list) { this.list = list; } @Override public Object next() { Object obj = null; if (this.hasNext()) { obj = this.list.get(cursor++); } return obj; } @Override public boolean hasNext() { if (cursor == list.size()) { return false; } return true; } }

3)容器角色

public interface Aggregate { public void add(Object obj); public void remove(Object obj); public Iterator iterator(); }

4) 具体容器角色

public class ConcreteAggregate implements Aggregate { private List list = new ArrayList(); @Override public void add(Object obj) { list.add(obj); } @Override public void remove(Object obj) { list.remove(obj); } @Override public Iterator iterator() { return new ConcreteIterator(list); } }

测试类

public class Client { public static void main(String[] args) { Aggregate ag = new ConcreteAggregate(); ag.add("小明"); ag.add("小红"); ag.add("小刚"); Iterator it = ag.iterator(); while (it.hasNext()) { String str = (String) it.next(); System.out.println(str); } }}

运行结果

小明 小红 小刚

四、迭代器优势和缺点

优势

    1)它支持以不一样的方式遍历一个聚合对象。
    2)迭代器简化了聚合类。
    3)在同一个聚合上能够有多个遍历。 
    4)在迭代器模式中,增长新的聚合类和迭代器类都很方便,无须修改原有代码。 

缺点

    因为迭代器模式将存储数据遍历数据职责分离,增长新的聚合类须要对应增长新的迭代器类,类的个数成对增长,这在必定程度上增长了系统的复杂性。

 

参考

其实这整篇文章几乎都来自该篇文章,用参考都不太好意思,哈哈。

     JAVA迭代器与迭代模式

 

想太多,作太少,中间的落差就是烦恼。想没有烦恼,要么别想,要么多作。中校【7】 

相关文章
相关标签/搜索