189 8069 5689

行为篇-迭代器模式-创新互联

文章目录
  • 前言
  • 一、物以类聚
  • 二、遍历标准化
  • 三、手写迭代器
    • 1.定义迭代器
    • 2.行车记录仪类
    • 3.客户端类
  • 总结

成都创新互联公司凭借专业的设计团队扎实的技术支持、优质高效的服务意识和丰厚的资源优势,提供专业的网站策划、成都网站设计、网站建设、网站优化、软件开发、网站改版等服务,在成都十年的网站建设设计经验,为成都成百上千中小型企业策划设计了网站。
前言

迭代,在程序中特指对某集合中各元素逐个取用的行为。迭代器模式(Iterator)提供了一种机制来按顺序访问集合中的各元素,而不需要知道集合内部的构造。换句话讲,迭代器满足了对集合迭代的需求,并向外部提供了一种统一的迭代方式,而不必暴露集合的内部数据结构。


提示:以下是本篇文章正文内容,下面案例可供参考

一、物以类聚

迭代的过程是基于一系列数据展开的,所以集合是不得不提的概念。物以类聚,集合是由一个或多个确定的元素构成的整体,其实就是把一系列类似的元素按某种数据结构集结起来,作为一个整体来引用,以便于维护。简单来讲,可以把集合理解为“一堆”或者“一群”类似的元素集结起来的整体。为了承载不同的数据形式,集合类提供了多种多样的数据结构,如我们常用的ArrayList、HashSet、HashMap等,

每种集合都有不同的特性,可以满足对各种数据结构的承载需求。有了集合才会产生对其迭代的需求,而每种数据结构的迭代方式又不尽相同,所以,定义标准化的迭代器势在必行,以提供统一、通用的使用方法。

二、遍历标准化

不同的数据结构需要不同的集合类,而针对不同的集合类的迭代方式也不尽相同,如for、foreach、while,甚至Java8引入的流式遍历等。举个例子,我们可以使用传统的for循环对List集合进行迭代遍历,而对于Set集合,for循环就无能为力了,这是因为Set本身集合不存在index索引号,所以必须用foreach循环(迭代器Iterator)进行遍历。难道就没有一种通用的迭代标准,能让调用者使用统一的方式进行遍历吗?如果我们深究源码就会发现,Collection接口中有这样一个接口。

Collection接口的一段源码,可以看到其明确声明了获取迭代器的接口iterator(),通过调用这个接口就可以返回标准的迭代器对象。既然有了这种标准,那么Collection这集合类就可以实现自己的迭代器。而Map集合也可以按照同样的方式,从其EntrySet中获取迭代器。可见,标准化的迭代器其实已经被各种集合类实现了,否则用户就无法站在Collection接口的抽象高度上对任何集合进行统一遍历。

三、手写迭代器

汽车前挡风玻璃上安装了一台行车记录仪,它最主要的一项功能就是记录行驶路途中所拍摄的视频信息,以防发生交通事故后作为证据之用。我们知道,行车记录仪所记录下来的视频文件是比较大的,同时其存储空间又是有限的,那么它是怎样确保一直不间断地录制视频,并且存储空间不被占满呢?这就需要我们深究其内部数据结构了。

其实,行车记录仪的视频录制存盘操作有循环覆写的特性,待空间不够用时,新录的视频就会覆盖最早的视频,以首尾相接的环形结构来解决存储空间有限的问题。

1.定义迭代器
public interface Iterator{//返回下一个元素
    E next();
    //是否还有下一个元素
    boolean hasNext();
}
2.行车记录仪类
public class DrivingRecorder{private int index = -1;//当前记录的位置
    private String[] records = new String[10]; //假设只能记录10条视频

    public void append(String record){//索引重置,从头覆盖
        if(index == 9 ){index = 0;
        }else {index++;
        }
        records[index] = record;
    }


    public Iteratoriterator() {return new Itr();
    }

    private class Itr implements Iterator{int cursor = index;//迭代器游标,不破及原始集合索引
        int loopCount = 0;

        @Override
        public String next() {int i = cursor;
            if(cursor == 0){cursor = 9;
            }else {cursor--;
            }
            loopCount++;
            return  records[i];
        }

        @Override
        public boolean hasNext() {return loopCount< 10;
        }
    }
}
3.客户端类
public class Client {public static void main(String[] args) {DrivingRecorder dr = new DrivingRecorder();
        for (int i = 0; i< 12; i++) {dr.append("视频_" + i);
        }
        ListuStorage = new ArrayList<>();
        Iterator it = dr.iterator();
        while (it.hasNext()){String video = (String) it.next();
            System.out.println(video);
            if("视频_10".equals(video) || "视频_8".equals(video)){uStorage.add(video);
            }
        }
        System.out.println("事故证据" + uStorage);
    }
}

输出结果:
视频_11
视频_10
视频_9
视频_8
视频_7
视频_6
视频_5
视频_4
视频_3
视频_2
事故证据[视频_10, 视频_8]

说明:

  1. 至此,我们实现的迭代器已经基本完成,用户不但可以使用Iterator进行迭代,而且foreach循环也得到了支持,用户再也不必为捉摸不定的迭代方式而犯愁了。当然,为保持简单,我们并没有实现迭代器的所有功能接口,例如对remove()功能接口的实现,利用这个接口用户便可以删除视频记录了。读者可以在此基础上继续代码实践,需要注意的是对迭代器游标的控制。
总结

提示:这里对文章进行总结:

  1. 为了完成对各种集合类的遍历,我们定义了统一的迭代器接口Iterator,基于此我们让集合以内部类的方式实现其特有的迭代逻辑,再将自己标记为Iterable并返回迭代器实例,以证明自己是具备迭代能力的。具体的集合内部结构与迭代逻辑对于客户端这个“局外人”是透明的,客户端只需要知道这个集合是可以迭代的,并向集合发起迭代请求以获取迭代器即可以进行标准方式的遍历了。

  2. 迭代器模式的各角色定义如下:

  • ConcreteAggregate(集合实现):实现集合接口Aggregate的具体集合类,可以实例化并返回一个迭代器以供外部使用。对应本章例程中的行车记录仪类DrivingRecorder。
  • Iterator(迭代器接口):迭代器的接口标准,定义了进行迭代操作所需的一些方法,如next()、hasNext()等。
  • ConcreteIterator(迭代器实现):迭代器接口Iterator的具体实现类,记录迭代状态并对外部提供所有迭代器功能的实现。
  • Client(客户端):集合数据的使用者,需要从集合获取迭代器再进行遍历。

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


本文题目:行为篇-迭代器模式-创新互联
分享路径:http://cdxtjz.cn/article/dpcgig.html

其他资讯