1.定义
迭代器模式属于行为模式,提供一种方法访问一个容器对象中各个元素,而又不暴露该对象的内部细节。
如果我们的集合元素是用不同的方式实现的,有数组,还有 java 的集合类,或者还有其他方式,当客户端要遍历这些集合元素的时候就要使用多种遍历方式,而且还会暴露元素的内部结构,可以考虑使用迭代器模式解决。
迭代器模式,提供一种遍历集合元素的统一接口,用一致的方法遍历集合元素,不需要知道集合对象的底层表示,即:不暴露其内部的结构。
2.迭代器结构
3.迭代器案例
需求:模拟一个人才市场的人员添加和遍历操作
interface Iterator { // 下一条数据(类型为Employee员工类型) public Employee next(); // 判断是否还有下一条数据 public boolean hasNext(); }
对象容器接口:模拟一个人才市场
interface EmploymentMarket { // 新增人员信息(身份证号,名称,年龄,技能) public void add(String idno , String name , Integer age , String skill); // 移除人员(根据身份证号判断) public void remove(String idno); // 提供一个迭代器,类型为Iterator public Iterator iterator(); }
雇员类:比较简单,标准的实体类
public class Employee { private String idno; private String name; private Integer age; private String skill; public Employee(String idno, String name, Integer age, String skill) { this.idno = idno; this.name = name; this.age = age; this.skill = skill; } public String getIdno() { return idno; } public void setIdno(String idno) { this.idno = idno; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getSkill() { return skill; } public void setSkill(String skill) { this.skill = skill; } }
容器实现:人才市场的实现类
public class EmploymentMarketImpl implements EmploymentMarket { // 定义四个集合分门别类的存储传入的数据 List<String> idnoList = new ArrayList(); List<String> nameList = new ArrayList(); List<Integer> ageList = new ArrayList(); List<String> skillList = new ArrayList(); @Override public void add(String idno, String name, Integer age, String skill) { synchronized (this) { // 如果传入的身份证号之前没有登记过,就对传入的属性进行分类存储 if(!idnoList.contains(idno)) { idnoList.add(idno); nameList.add(name); ageList.add(age); skillList.add(skill); } } } @Override public void remove(String idno) { synchronized (this) { // 判断传入的身份证号是否存在,存在则移除 int idx = idnoList.indexOf(idno); if(idx != -1) { idnoList.remove(idx); nameList.remove(idx); ageList.remove(idx); skillList.remove(idx); } } } @Override // 迭代器 public Iterator iterator() { return new EmployeeIterator(idnoList,nameList,ageList,skillList); } }
迭代器实现:封装了遍历和迭代转化的过程
public class EmployeeIterator implements Iterator{ // 游标:定义数据的前一个值 int cursor = -1; List<String> idnoList ; List<String> nameList ; List<Integer> ageList ; List<String> skillList ; // 外侧传入四个构造参数才能实例化构造对象 public EmployeeIterator(List<String> idnoList,List<String> nameList , List<Integer> ageList,List<String> skillList){ this.idnoList = idnoList; this.nameList = nameList; this.ageList = ageList; this.skillList = skillList; } @Override // 数据提取过程 public Employee next() { if(hasNext()) { // 游标位置向后移动 ++cursor; // 将后一条数据的游标传入每一个list集合中,提取下一条数据每一个值 Employee employee = new Employee(idnoList.get(cursor), nameList.get(cursor), ageList.get(cursor), skillList.get(cursor)); return employee; }else{ // 如果没有数据就返回null return null; } } @Override // 判断是否还有下一个数据 public boolean hasNext() { if(cursor < idnoList.size()-1){ return true; }else { return false; } } }
客户端:
public class Client { public static void main(String[] args) { // 创建人才市场实现类,并初始化数据 EmploymentMarket market = new EmploymentMarketImpl(); market.add("130102XXXXXXXX0524","张燕",37,"IT产品销售"); market.add("130104XXXXXXXX1928","李晶",28,"地产策划"); market.add("130203XXXXXXXX0911","吴宇森",55,"电影导演"); // 得到迭代器对象 Iterator iterator = market.iterator(); // 遍历人才市场相关数据 while (iterator.hasNext()){ Employee employee = iterator.next(); System.out.println(employee); } } }
4.迭代器优点
1、简化了遍历⽅式,对于对象集合的遍历,还是⽐较麻烦的,对于数组或者有序列表,我们尚可以通过游标来取得,但⽤户需要在对集合了解很清楚的前提下,⾃⾏遍历对象,但是对于hash表来说,⽤户遍历起来就⽐较麻烦了。⽽引⼊了迭代器⽅法后,⽤户⽤起来就简单的多了。
2、可以提供多种遍历⽅式,⽐如说对有序列表,我们可以根据需要提供正序遍历,倒序遍历两种迭代器,⽤户⽤起来只需要得到我们实现好的迭代器,就可以⽅便的对集合进⾏遍历了。
3、封装性良好,⽤户只需要得到迭代器就可以遍历,⽽对于遍历算法则不⽤去关⼼。
5.迭代器缺点
对于⽐较简单的遍历(像数组或者有序列表),使⽤迭代器⽅式遍历较为繁琐,⼤家可能都有感觉,像ArrayList,我们宁可愿意使⽤for循环和get⽅法来遍历集合。
6.应用场景
Java集合类
复杂的数据结构,对客户端只暴露最简单的Iterator迭代器即可
转载请注明:西门飞冰的博客 » 设计模式—迭代器模式