设计模式学习笔记(十六)迭代器模式及其在Java 容器中的应用
2022-04-06 21:58
1121 查看
迭代器(Iterator)模式,也叫做游标(Cursor)模式。我们知道,在Java 容器中,为了提高容器遍历的方便性,把遍历逻辑从不同类型的集合类中抽取出来,避免向外部暴露集合容器的内部结构。
一、迭代器模式介绍
迭代器模式也就是提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。它是一种行为型模式,下面就来看看迭代器模式的结构:
1.1 迭代器模式的结构
迭代器模式的结构很简单,就是将聚合对象中的遍历行为分离,并抽象成迭代器类来实现:
Aggregate
:抽象聚合接口,定义对聚合对象的一些操作和创建迭代器对象的接口Iterator
:抽象迭代器接口,定义访问和遍历聚合元素的接口Aggregate1
:具体聚合实现,实现抽象聚合接口,返回一个具体迭代器实例对象Iterator1
:具体迭代器实现,实现抽象迭代器接口中所定义的方法
1.2 迭代器模式的实现
根据上面的类图,可以实现如下代码:
/** * @description: 抽象聚合接口 * @author: wjw * @date: 2022/4/6 */ public interface Aggregate { /** * 增加对象 * @param obj 对象 */ void add(Object obj); /** * 移除对象 * @param obj 对象 */ void remove(Object obj); /** * 调用迭代器 * @return 迭代器 */ Iterator getIterator(); } /** * @description: 具体迭代器类 * @author: wjw * @date: 2022/4/6 */ public class Aggregate1 implements Aggregate{ private List<Object> list = new ArrayList<>(); @Override public void add(Object obj) { list.add(obj); } @Override public void remove(Object obj) { list.remove(obj); } @Override public Iterator getIterator() { return new Iterator1(list); } } /** * @description: 抽象迭代器 * @author: wjw * @date: 2022/4/6 */ public interface Iterator { /** * 调用第一个对象 * @return 对象 */ Object first(); /** * 调用下一个对象 * @return 对象 */ Object next(); /** * 迭代器中是否还有下一个对象 * @return */ boolean hasNext(); } /** * @description: 具体迭代器类 * @author: wjw * @date: 2022/4/6 */ public class Iterator1 implements Iterator{ private List<Object> list = null; private int index = -1; public Iterator1(List<Object> list) { this.list = list; } @Override public Object first() { index = 0; Object obj = list.get(index); return obj; } @Override public Object next() { Object obj = null; if (this.hasNext()) { obj = list.get(++index); } return obj; } @Override public boolean hasNext() { if (index < list.size() - 1) { return true; } else { return false; } } } /** * @description: 客户端类 * @author: wjw * @date: 2022/4/6 */ public class Client { public static void main(String[] args) { Aggregate1 aggregate1 = new Aggregate1(); aggregate1.add("A"); aggregate1.add("B"); aggregate1.add("C"); System.out.println("聚合对象有:"); Iterator iterator = aggregate1.getIterator(); while (iterator.hasNext()) { Object obj = iterator.next(); System.out.println(obj.toString()); } Object first = iterator.first(); System.out.println("第一个聚合对象是:" + first.toString()); } }
客户端测试场结果为:
聚合对象有: A B C 第一个聚合对象是:A
二、迭代器模式的应用场景
2.1 Java 集合容器
Java 集合容器中的使用就是容器中的迭代器了,以
ArrayList为例,
ArrayList是继承
Collection的:
我们发现
ArrayList类里面实现迭代器接口的内部类:
其中
Itr实现
Iterator,
ListItr继承
Itr并实现
ListIterator,
ListIterator是
Iterator功能的扩展。所以实际上
ArrayList是抽象聚合和抽象迭代器两者的具体实现,可以画出大致结构图如下:
举个使用
ArrayList的例子:
public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("A"); list.add("B"); list.add("C"); Iterator<String> iterator = list.iterator(); System.out.println("ArrayList中的聚合对象为:"); while (iterator.hasNext()) { String next = iterator.next(); System.out.println(next); } }
输出结果:
ArrayList中的聚合对象为: A B C
在日常业务的开发中,迭代器模式使用的场景并不多,下面就来看看关于迭代器的实战
三、迭代器模式实战
在本案例中模拟迭代遍历输出公司中树形结构的组织结构关系中雇员列表:
利用迭代器模式实现的结构如下:
上面结构是以Java容器中迭代器模式基础构建的,左边是迭代器的定义,右边是实现的迭代器功能。具体代码结构图如下:
├─src │ ├─main │ │ ├─java │ │ │ ├─group │ │ │ │ Employee.java │ │ │ │ GroupStructure.java │ │ │ │ Link.java │ │ │ │ │ │ │ └─lang │ │ │ Collection.java │ │ │ Iterable.java │ │ │ Iterator.java │ │ │ │ │ └─resources │ └─test │ └─java │ ApiTest.java
对于
lang包下是迭代器实现部分,具体代码如下:
/** * @description: 可迭代接口定义 * @author: wjw * @date: 2022/4/6 */ public interface Iterator<E> { boolean hasNext(); E next(); } /** * @description: * @author: wjw * @date: 2022/4/6 */ public interface Iterable<E> { Iterator<E> iterator(); } /** * @description: 集合功能接口 * @author: wjw * @date: 2022/4/6 */ public interface Collection<E, L> extends Iterable<E> { boolean add(E e); boolean remove(E e); boolean addLink(String key, L l); boolean removeLink(String key); /** * 继承Iterable接口的方法 * @return Iterator */ @Override Iterator<E> iterator(); }
group包下是组织结构以及聚类对象及其实现,具体代码如下所示:
/** * @description: 雇员类 * @author: wjw * @date: 2022/4/6 */ public class Employee { private String uId; private String name; private String desc; public Employee(String uId, String name, String desc) { this.uId = uId; this.name = name; this.desc = desc; } public String getuId() { return uId; } public void setuId(String uId) { this.uId = uId; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } } /** * @description: 树节点链路 * @author: wjw * @date: 2022/4/6 */ public class Link { private String fromId; private String toId; public Link(String fromId, String toId) { this.fromId = fromId; this.toId = toId; } public String getFromId() { return fromId; } public void setFromId(String fromId) { this.fromId = fromId; } public String getToId() { return toId; } public void setToId(String toId) { this.toId = toId; } } /** * @description: 迭代器功能实现 * @author: wjw * @date: 2022/4/6 */ public class GroupStructure implements Collection<Employee, Link> { /**组织ID*/ private String groupId; /**组织名称*/ private String groupName; /**雇员列表*/ private Map<String, Employee> employeeMap = new ConcurrentHashMap<>(); /**组织架构关系*/ private Map<String, List<Link>> linkMap = new ConcurrentHashMap<>(); /**反向关系链*/ private Map<String, String> invertedMap = new ConcurrentHashMap<>(); public GroupStructure(String groupId, String groupName) { this.groupId = groupId; this.groupName = groupName; } @Override public boolean add(Employee employee) { return null != employeeMap.put(employee.getuId(), employee); } @Override public boolean remove(Employee employee) { return null != employeeMap.remove(employee.getuId()); } @Override public boolean addLink(String key, Link link) { invertedMap.put(link.getToId(), link.getFromId()); if (linkMap.containsKey(key)) { return linkMap.get(key).add(link); } else { List<Link> links = new LinkedList<>(); links.add(link); linkMap.put(key, links); return true; } } @Override public boolean removeLink(String key) { return null != linkMap.remove(key); } @Override public Iterator<Employee> iterator() { return new Iterator<Employee>() { HashMap<String, Integer> keyMap = new HashMap<>(); int totalIdx = 0; //雇员ID,From private String fromId = groupId; //雇员ID,To private String toId = groupId; @Override public boolean hasNext() { return totalIdx < employeeMap.size(); } @Override public Employee next() { List<Link> links = linkMap.get(toId); int cursorIdx = getCursorIdx(toId); //同级扫描 if (null == links) { cursorIdx = getCursorIdx(fromId); links = linkMap.get(fromId); } //上级节点扫描 while (cursorIdx > links.size() - 1) { fromId = invertedMap.get(fromId); cursorIdx = getCursorIdx(fromId); links = linkMap.get(fromId); } //获取节点 Link link = links.get(cursorIdx); toId = link.getToId(); fromId = link.getFromId(); totalIdx++; //返回最终结果 return employeeMap.get(link.getToId()); } //给每个层级定义宽度遍历进度 public int getCursorIdx(String key) { int idx = 0; if (keyMap.containsKey(key)) { idx = keyMap.get(key); keyMap.put(key, ++idx); } else { keyMap.put(key, idx); } return idx; } }; } }
最后是测试类及其结果:
/** * @description: 单元测试类 * @author: wjw * @date: 2022/4/6 */ public class ApiTest { private Logger logger = LoggerFactory.getLogger(ApiTest.class); @Test public void test_iterator() { GroupStructure groupStructure = new GroupStructure("1", "ethan"); groupStructure.add(new Employee("2", "花花", "二级部门")); groupStructure.add(new Employee("3", "豆包", "二级部门")); groupStructure.add(new Employee("4", "蹦蹦", "三级部门")); groupStructure.add(new Employee("5", "大烧", "三级部门")); groupStructure.add(new Employee("6", "虎哥", "四级部门")); groupStructure.add(new Employee("7", "玲姐", "四级部门")); groupStructure.add(new Employee("8", "秋雅", "四级部门")); //添加节点链接 groupStructure.addLink("1", new Link("1", "2")); groupStructure.addLink("1", new Link("1", "3")); groupStructure.addLink("2", new Link("2", "4")); groupStructure.addLink("2", new Link("2", "5")); groupStructure.addLink("5", new Link("5", "6")); groupStructure.addLink("5", new Link("5", "7")); groupStructure.addLink("5", new Link("5", "8")); Iterator<Employee> iterator = groupStructure.iterator(); while (iterator.hasNext()) { Employee employee = iterator.next(); logger.info("{},雇员 Id: {} Name: {}", employee.getDesc(), employee.getuId(), employee.getName()); } } }
21:50:11.087 [main] INFO ApiTest - 二级部门,雇员 Id: 2 Name: 花花 21:50:11.089 [main] INFO ApiTest - 三级部门,雇员 Id: 4 Name: 蹦蹦 21:50:11.089 [main] INFO ApiTest - 三级部门,雇员 Id: 5 Name: 大烧 21:50:11.089 [main] INFO ApiTest - 四级部门,雇员 Id: 6 Name: 虎哥 21:50:11.089 [main] INFO ApiTest - 四级部门,雇员 Id: 7 Name: 玲姐 21:50:11.089 [main] INFO ApiTest - 四级部门,雇员 Id: 8 Name: 秋雅 21:50:11.089 [main] INFO ApiTest - 二级部门,雇员 Id: 3 Name: 豆包
参考资料
《重学Java设计模式》
相关文章推荐
- 设计模式学习笔记(十一)外观模式及其应用场景
- 设计模式学习笔记--设计模式在Java I/O中的应用(装饰模式和适配器模式)
- java学习笔记-设计模式17(迭代器模式)
- 设计模式学习笔记十六:迭代器模式
- java/android 设计模式学习笔记(20)---迭代器模式
- 十六、迭代器模式——设计模式学习笔记
- Java-马士兵设计模式学习笔记-迭代器模式-模仿Collectin ArrayList LinckedList
- 设计模式学习笔记---迭代器模式iterator pattern(Java版)
- JAVA与模式学习笔记之设计原则
- [学习笔记]jsp+javaBean+Servlet 的设计模式MVC 的实例
- java 设计模式学习笔记五Adapter适配器模式
- NET 应用架构指导 V2 学习笔记(十六) 服务层设计指导
- 设计模式学习笔记-迭代器模式
- java 设计模式学习笔记十一flyweight享元设计模式
- 设计模式学习笔记之策略模式(Java实现)
- java 设计模式 学习笔记(3) 抽象工厂模式
- 设计模式学习笔记5:Singleton模式及其Delphi实现
- Java学习笔记四。设计模式、基本数据类型、包装类、异常、断言、包、访问权限、命名规范、jar
- java 设计模式学习笔记十二 command命令设计模式
- 设计模式C++学习笔记之十四(Iterator迭代器模式)