文章目录
迭代器模式情景
- 迭代器模式情景
- 迭代器模式实战
在jdk中已经提供了迭代器模式, 用于集合的迭代遍历. 实现Iterable 接口, 通过next的方式, 获取集合元素. 同时具备对元素的删除等操作. 优点是以相同的方式遍历不同数据结构的元素, 不用去关心迭代的数据的结构, 让使用者变得统一易用.
迭代器模式实战模拟公司部门迭代. 创建雇员类 .
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Employee {
// id
private String uId;
// 姓名
private String name;
// 备注
private String desc;
}
创建树节点链路.
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Link {
// 上一个雇员id
private String fromId;
// 下一个雇员id
private String toId;
}
迭代器定义
public interface Iterator {
boolean hasNext();
E next();
}
可迭代接口定义
public interface Iterable {
Iterator iterator();
}
集合功能接口定义
public interface Collection extends Iterable {
boolean add(E e);
boolean remove(E e);
//定义了两个泛型,因为数据结构一个是用于添加元素,另外一个是用于添加树节点的链路关系。
boolean addLink(String key, L l);
boolean removeLink(String key);
Iterator iterator();
}
迭代器功能实现 (核心)
public class GroupStructure implements Collection {
// 组织id
private String groupId;
//组织名称
private String groupName;
// 雇员列表
private Map employeeMap = new ConcurrentHashMap();
// 组织架构关系 id - > list
private Map linkMap = new ConcurrentHashMap();
// 反向关系链
private Map invertedMap = new ConcurrentHashMap();
public GroupStructure(String groupId, String groupName) {
this.groupId = groupId;
this.groupName = groupName;
}
public boolean add(Employee employee) {
return employeeMap.put(employee.getUId(), employee) != null;
}
public boolean remove(Employee employee) {
return employeeMap.remove(employee.getUId()) != null;
}
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 links = new LinkedList();
links.add(link);
linkMap.put(key, links);
return true;
}
}
public boolean removeLink(String key) {
return linkMap.remove(key)!=null;
}
public Iterator iterator() {
return new Iterator() {
HashMap keyMap = new HashMap();
int totalIdx = 0;
private String fromId = groupId;
private String toId = groupId;
public boolean hasNext() {
return totalIdx 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());
}
private int getCursorIdx(String key) {
int idx = 0;
if (keyMap.containsKey(key)){
idx = keyMap.get(key);
// 游标加1
keyMap.put(key, ++idx);
} else {
keyMap.put(key, idx);
}
return idx;
}
};
}
}
测试类
public class ApiTest {
@Test
public void test_Iterator() {
GroupStructure groupStructure = new GroupStructure("1", "周杰伦");
// 雇员信息
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"));
// id为2的, 下面有4, 5 两个人员
groupStructure.addLink("2", new Link("2", "4"));
groupStructure.addLink("2", new Link("2", "5"));
// id为5的人, 下面有6, 7,8 这三个人员
groupStructure.addLink("5", new Link("5", "6"));
groupStructure.addLink("5", new Link("5", "7"));
groupStructure.addLink("5", new Link("5", "8"));
Iterator iterator = groupStructure.iterator();
while (iterator.hasNext()) {
Employee next = iterator.next();
System.out.println("雇员描述: " + next.getDesc() + "雇员id: " + next.getUId() + "雇员姓名: " + next.getName());
}
}
}
结果如下 . 实现了遍历
雇员描述: 二级部门雇员id: 2雇员姓名: 花花 雇员描述: 三级部门雇员id: 4雇员姓名: 蹦蹦 雇员描述: 三级部门雇员id: 5雇员姓名: 大烧 雇员描述: 四级部门雇员id: 6雇员姓名: 虎哥 雇员描述: 四级部门雇员id: 7雇员姓名: 琳姐 雇员描述: 四级部门雇员id: 8雇员姓名: 秋雅 雇员描述: 二级部门雇员id: 3雇员姓名: 豆包