设计模式之迭代器模式

前言 :
为什么要引入这种Iterator这种模式?

    数组直接用for循环不就好了吗~重要的理由就是可以将遍历与实现分离开来。

目的:提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。

    这里的顺序访问即迭代器的种类,可以从后往前遍历,也可以跳跃式遍历。

不要只使用具体类来编程、要优先使用抽象类和接口来编程

迭代器模式中的角色:
迭代器角色(Iterator): 负责定义访问和遍历元素的接口。
具体迭代器角色(Concrete Iterator):实现迭代器接口,并要记录遍历中的当前位置。
容器角色(Container): 负责提供创建具体迭代器角色的接口。
具体容器角色(Concrete Container):实现创建具体迭代器角色的接口, 这个具体迭代器角色与该容器的结构相关。
迭代器接口:
最常用的就是 hasNext、next方法,前者判断是否存在下一个元素,后者用于获取该元素。

当然还有remove方法,但是在Java中,没有被使用的对象实例将会自动的被删除(GC)

public interface Iterator {
public abstract boolean hasNext();
public abstract Object next();
}
具体的迭代器:
next方法是返回当前元素,并指向下一个元素。

hasNext返回的是boolean,表示当前集合是否存在下一个元素,大概就是确认接下来是否可以调用next方法。

public class BookShelfIterator implements Iterator{
private BookShelf bookShelf;
private int index;

public BookShelfIterator(BookShelf bookShelf) {
    this.bookShelf = bookShelf;
    this.index = 0;
}

@Override
public boolean hasNext() {
    if(index < bookShelf.getLength()){
        return true;
    }else {
        return false;
    }
}

@Override
public Object next() {
    Book book = bookShelf.getBookAt(index);
    index ++;
    return book;
}

}
容器接口:
// 表示该方法只会生成一个用于遍历集合的迭代器
public interface Aggregate {
public abstract Iterator iterator();
}
具体容器实现:
该数组的大小在实例化就被指定了,Iterator方法会生成并返回这个实例。当外部想遍历书架,就会调用这个方法。

public class BookShelf implements Aggregate{
//容器中装着书
private Book[] books;
private int last = 0;

public BookShelf(int maxsize) {
    this.books = new Book[maxsize];
}

public Book getBookAt(int index) {
    return books[index];
}

public void appendBook(Book book){
    this.books[last] = book;
    last ++;
}
public int getLength(){
    return last;
}


@Override
public Iterator iterator() {
    return new BookShelfIterator(this);
    //加this是该实例的构造方法要传入一个BookShelf的对象
}

}
实体Book类:
public class Book {
private String name;

public Book(String name) {
    this.name = name;
}

public String getName() {
    return name;
}

}
Main:
public class Main {
public static void main(String[] args) {
BookShelf bookShelf = new BookShelf(4);
bookShelf.appendBook(new Book(“one book”));
bookShelf.appendBook(new Book(“two book”));
bookShelf.appendBook(new Book(“three book”));
bookShelf.appendBook(new Book(“four book”));

    Iterator it = bookShelf.iterator();
    while(it.hasNext()){
        Book book = (Book)it.next();
        System.out.println(book.getName());
    }
}

}
BookShelfIterator类发挥了Iterator的作用,构造函数会将集合实例保存在字段中,并初始index、
Iterator it = bookShelf.iterator();
多态性: 运行期的代码返回的是实现Iterator接口的、而实现Iterator接口的构造方法中又传入了该集合实例、 编译期的代码本身就是写成接口形式。

实用:
上述迭代器实现的基本原理,在大部分集合中都有实现好了迭代器的用法,而且上述的容器用的是数组、那么就会存在满了越界的情况,解决办法就是每次添加前判断是否越界、扩容方案、直接用集合。

import java.util.ArrayList;
import java.util.Iterator;

public class test {
public static void main(String[] args) {
ArrayList array = new ArrayList(); // List接口实现了Iterable接口
array.add(“one book”);
array.add(“two book”);
array.add(“three book”);
array.add(“four book”);

    Iterator<String> iterator = array.iterator();

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

}
注意了,前面的Iterator是我自己实现了,这里才是导入了Java自带的util包~~

练习~
import java.util.Iterator;

public class MyString implements Iterable{

private int length;
private String str;

public MyString(String str) {
    this.str = str;
    this.length = str.length();
}

@Override
public Iterator<Character> iterator() {

    class iter implements Iterator<Character>{

        private int cur = 0;

        @Override
        public boolean hasNext() {
            return cur < length ? true : false;
        }

        @Override
        public Character next() {
            Character c = str.charAt(cur);
            cur += 2;
            return c;
        }

    }
    return new iter();   //实现Iterabler的接口,返回迭代器
}

}
// 自定义类的迭代,如跳跃取字符串字符
public class Main {

public static void main(String[] args) {
    MyString str = new MyString("123456789");

    for(char c : str){
        System.out.print(c);
    }
}

}

注~ 别忘了初衷,当时是看图的遍历用迭代器的形式来归纳一下、

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端成神之路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值