设计模式之Iterator(二)
2016-04-27 22:26
211 查看
在上一节的基础上,考虑遍历容器
实现一的优化
定义接口
在Collection接口中添加抽象方法
在ArrayList容器中实现iterator方法,返回Iterator接口的对象
测试类中调用Iterator接口的方法
实现二的优化
接口Iterator、Collection的定义保持不变
在LinkedList容器中实现iterator方法,返回Iterator接口的对象
测试类中调用Iterator接口的方法
package com.awiatech.iterator; import com.awiatech.iterator.ArrayList; import com.awiatech.iterator.LinkedList; /** * 测试类用于测试容器的功能。 * @author Chicago * */ public class Test { public static void main(String[] args) { // ArrayList al = new ArrayList(); // LinkedList al = new LinkedList(); // 面向接口编程,好处:灵活、可扩展 Collection c = new ArrayList(); // 父类引用指向子类对象 for(int i = 0; i < 15; i ++){ c.add(new Object()); } System.out.println(c.size()); // 考虑遍历容器 ArrayList al = (ArrayList)c; for(int i = 0; i < al.index; i ++){ } } }然而,每种容器都有自己的遍历方式,应想方设法进行统一。每种容器具体遍历的实现不太一样,那么统一时只能用一种共同的接口或抽象类的方式实现。
实现一的优化
定义接口
package com.awiatech.iterator; public interface Iterator { public Object next(); public boolean hasNext(); }
在Collection接口中添加抽象方法
package com.awiatech.iterator; public interface Collection { public void add(Object o); public int size(); public Iterator iterator(); }
在ArrayList容器中实现iterator方法,返回Iterator接口的对象
package com.awiatech.iterator; /** * 一个动态添加对象的容器,底层使用数组模拟。 * 与数组相比的好处:不用考虑数组的边界问题,可以动态扩展。 * @author Chicago * */ public class ArrayList implements Collection{ Object[] objects = new Object[10]; // 定义一个长度为10的数组 int index = 0; // 数组索引指向 /** * 数组中添加元素 * @param o 要添加的元素 */ public void add(Object o){ // 当原数组数据满时再开辟两倍长度的新数组,并拷贝原数组数据至新数组中,并将原数组指向新数组 if(index == objects.length){ Object[] newObjects = new Object[objects.length * 2]; System.arraycopy(objects, 0, newObjects, 0, objects.length); objects = newObjects; } objects[index] = o; // 元素添加到数组 index ++; // 移动索引指向 } /** * 数组中元素的个数 * @return 返回数组中元素的个数 */ public int size(){ return index; } /** * 实现了Iterator接口的对象,对于类名并不重要,完全可以定义一个匿名类。 */ public Iterator iterator(){ return new ArrayListIterator(); } /** * 简单的定义一个内部类。 */ public class ArrayListIterator implements Iterator{ private int currentIndex = 0; @Override public Object next() { // 得到下一个 Object o = objects[currentIndex]; currentIndex ++; return o; } @Override public boolean hasNext() { // 是否有下一个 if(objects[currentIndex] == null) return false; else return true; } } }
测试类中调用Iterator接口的方法
package com.awiatech.iterator; import com.awiatech.iterator.ArrayList; import com.awiatech.iterator.LinkedList; /** * 测试类用于测试容器的功能。 * @author Chicago * */ public class Test { public static void main(String[] args) { // ArrayList al = new ArrayList(); // LinkedList al = new LinkedList(); // 面向接口编程,好处:灵活、可扩展 Collection c = new ArrayList(); // 父类引用指向子类对象 for(int i = 0; i < 15; i ++){ c.add(new Cat(i)); } System.out.println(c.size()); // 考虑遍历容器 // ArrayList al = (ArrayList)c; // for(int i = 0; i < al.index; i ++){ // // } Iterator it = c.iterator(); while(it.hasNext()){ Object o = it.next(); System.out.print(o + " "); } } }借助于另一个Cat类测试,定义如下
package com.awiatech.iterator; public class Cat { public Cat(int id) { super(); this.id = id; } private int id; public int getId() { return id; } public void setId(int id) { this.id = id; } public String toString(){ return "cat" + id; } }
实现二的优化
接口Iterator、Collection的定义保持不变
在LinkedList容器中实现iterator方法,返回Iterator接口的对象
package com.awiatech.iterator; /** * 一个动态添加对象的容器,底层使用链表模拟。 * @author Chicago * */ public class LinkedList implements Collection{ Node head = null; // 链表头 Node tail = null; // 链表尾 int size = 0; // 链表中元素个数 /** * 链表中添加元素 * @param o 要添加的元素 */ public void add(Object o){ Node n = new Node(o, null); // 构造要添加的节点 // 若链表为空,则将链表头和尾都指向新节点 if(head == null){ head = n; tail = n; } tail.setNext(n); // 原链表尾指向新节点 tail = n; // 链表尾重定向到新节点 size ++; // 链表中元素数量累加 } /** * 链表中元素的个数 * @return 返回链表中元素的个数 */ public int size(){ return size; } @Override public Iterator iterator() { return new LinkedListIterator(); } /** * 简单定义一个内部类。 * @author Chicago * */ private class LinkedListIterator implements Iterator{ Node index = head; @Override public Object next() { // 得到下一个 Object o = index.getData(); index = index.getNext(); return o; } @Override public boolean hasNext() { // 是否有下一个 if(index.getNext() == null && tail.getNext() == null) return false; else return true; } } }
测试类中调用Iterator接口的方法
package com.awiatech.iterator; import com.awiatech.iterator.ArrayList; import com.awiatech.iterator.LinkedList; /** * 测试类用于测试容器的功能。 * @author Chicago * */ public class Test { public static void main(String[] args) { // ArrayList al = new ArrayList(); // LinkedList al = new LinkedList(); // 面向接口编程,好处:灵活、可扩展 // Collection c = new ArrayList(); // 父类引用指向子类对象 Collection c = new LinkedList(); for(int i = 0; i < 15; i ++){ c.add(new Cat(i)); } System.out.println(c.size()); // 考虑遍历容器 // ArrayList al = (ArrayList)c; // for(int i = 0; i < al.index; i ++){ // // } Iterator it = c.iterator(); while(it.hasNext()){ Object o = it.next(); System.out.print(o + " "); } } }
相关文章推荐
- PropertyChangeListener简单理解
- 什么是设计模式
- 设计模式之创建型模式 - 特别的变量问题
- 七、设计模式——装饰模式
- 设计模式总结
- 设计模式之创建型模式
- 浅谈设计模式的学习
- 文件遍历排序函数
- On Error Resume Next 语句
- Ruby设计模式编程之适配器模式实战攻略
- 实例讲解Ruby使用设计模式中的装饰器模式的方法
- 设计模式中的模板方法模式在Ruby中的应用实例两则
- Ruby设计模式编程中对外观模式的应用实例分析
- 实例解析Ruby设计模式编程中Strategy策略模式的使用
- Ruby中使用设计模式中的简单工厂模式和工厂方法模式
- Ruby使用设计模式中的代理模式与装饰模式的代码实例
- VBS For Next循环的陷阱分享
- Lua 学习笔记之C API 遍历 Table实现代码
- 详解组合模式的结构及其在Ruby设计模式编程中的运用
- VBS For Next循环的一些细节