迭代器模式

迭代器模式

说起迭代器,我们会比较熟悉,Iterator,出现在聚合里,提供了访问聚合中包含的对象的功能,迭代器提供了一系列相同的方法,比如hasnext()、next()等等,我们利用迭代器对聚合进行访问时,不需要知道聚合中如何存储存储一系列对象,我们只需要操作迭代器来进行访问。
迭代器模式把访问聚合对象的功能抽取出来,如何访问对象由迭代器自己实现,使聚合对其包含对象的访问中解耦出来。
下面是结构图,十分简单:
在这里插入图片描述
迭代器只需要实现Iterator结构,自己实现里面的方法,我这里只实现了hasNext跟next方法,下面我把它应用到上一次讲的组合模式中,让组合模式中的文件夹不需要编写对其所包含的文件的访问,访问功能有迭代器提供。

FileCompoment改造:

public interface FileCompoment {
    Iterator iterator(); //增加了一个接口,用来获取迭代器
}



public class FileBase implements FileCompoment{
    @Override
    public Iterator iterator() {
        return new NullIterator(); //返回一个空迭代器,hasNext()方法一定是false
    }
}




public class FolderBase implements FileCompoment {
    @Override
    public void print() {
// 注释掉原本的对包含的文件的遍历,交由迭代器处理,只打印出自己的文件名
//        Iterator<FileCompoment> iterator = fileCompoments.iterator();
          System.out.format("folerName = {%s}\r\n",fileName);
//        while (iterator.hasNext()){
//            FileCompoment fileCompoment = iterator.next();
//            fileCompoment.print();
//        }
    }

    @Override
    public Iterator iterator() {
        return new FileIterator(fileCompoments.iterator()); //返回一个文件迭代器
    }

    public List<FileCompoment> getFileCompoments() {
        return fileCompoments;
    }
}

迭代器代码:

// 空迭代器
public class NullIterator implements Iterator {
    @Override
    public boolean hasNext() {
        return false;
    }

    @Override
    public Object next() {
        return null;
    }
}



// 文件迭代器
public class FileIterator implements Iterator<FileCompoment> {
    // 由于文件夹是树状结构,其中可能还会包含其他文件夹,所以用栈来装载Iterator
    Stack<Iterator> iteratorStack;

    public FileIterator(FolderBase folderBase) {
        iteratorStack = new Stack<>();
        // 最外层的文件夹也要加载
        List list = new ArrayList();
        list.add(folderBase);
        iteratorStack.push(list.iterator());
    }

    @Override
    public boolean hasNext() {
        // 如果栈不为空,则获取栈顶迭代器
        while (!iteratorStack.isEmpty()) {
            Iterator iterator = iteratorStack.peek();
            // 如果栈顶迭代器有下一个元素,返回true,否则弹出栈顶迭代器
            if (iterator.hasNext()) {
                return true;
            }else {
                iteratorStack.pop();
            }
        }
        return false;
    }

    @Override
    public FileCompoment next() {
        Iterator iterator = iteratorStack.peek();
        Object fileCompoment =iterator.next();
        // 如果迭代器获取的元素是文件夹,把文件夹包含的容器的迭代器装载入栈,迭代完这个文件夹后才弹出继续上一层的迭代
        if(fileCompoment instanceof FolderBase){
            iteratorStack.push(((FolderBase)fileCompoment).getFileCompoments().iterator());
        }
        return (FileCompoment) fileCompoment;
    }
}

测试代码:

public class Main {

    public static void main(String[] args) throws Exception{
        FileCompoment folder1 = new FolderBase("folder1");

        FileCompoment file1 = new FileBase("file1");
        FileCompoment file2 = new FileBase("file2");
        FileCompoment folder2 = new FolderBase("folder2");
        folder1.addFile(file1);
        folder1.addFile(file2);
        folder1.addFile(folder2);


        FileCompoment file3 = new FileBase("file3");
        FileCompoment folder3 = new FolderBase("folder3");
        folder2.addFile(file3);
        folder2.addFile(folder3);

        FileCompoment file4 = new FileBase("file4");
        FileCompoment file5 = new FileBase("file4");
        folder3.addFile(file4);
        folder3.addFile(file5);

        Iterator<FileCompoment> iterator = folder1.iterator();
        while (iterator.hasNext()){
            FileCompoment fileCompoment = iterator.next();
            fileCompoment.print();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值