您的位置:首页 > 其它

设计模式之Iterator(二)

2016-04-27 22:26 211 查看
在上一节的基础上,考虑遍历容器

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 + " ");
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息