欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java设计模式之迭代器模式

程序员文章站 2024-03-22 09:23:52
...

迭代器用来按某种顺序取出集合中的元素。代码:

package com.zhangxf.iterator;

// 迭代器接口
interface MyIteratorInf<T> {
	public boolean hasNext();

	public T next();
}

// 支持正向迭代器的类要实现这个接口
interface ForwardIteratorAble<T> {
	public MyIteratorInf<T> getForwardIterator();
}

// 支持逆向迭代器的类要实现这个接口
interface ReverseIteratorAble<T> {
	public MyIteratorInf<T> getReverseIterator();
}

class MyQuene<T> implements ForwardIteratorAble<T>, ReverseIteratorAble<T> {
	private Object[] c;
	private int index;

	private class MyForwardIteratorImpl implements MyIteratorInf<T> {
		private int index = 0;

		@Override
		public boolean hasNext() {
			if (index < c.length) {
				return true;
			}
			return false;
		}

		@SuppressWarnings("unchecked")
		@Override
		public T next() {
			if (hasNext()) {
				return (T) c[index++];
			}
			return null;
		}
	}

	private class MyReverseIteratorImpl implements MyIteratorInf<T> {
		private int index = 0;

		@Override
		public boolean hasNext() {
			if (index < c.length) {
				return true;
			}
			return false;
		}

		@SuppressWarnings("unchecked")
		@Override
		public T next() {
			if (hasNext()) {
				return (T) c[(c.length - 1) - index++];
			}
			return null;
		}
	}

	public MyQuene(int size) {
		// 不可以,编译器报“Cannot create a generic array of T”
		// c = new T[size];
		c = new Object[size];
		index = 0;
	}

	// 添加元素
	public boolean add(T item) {
		if (index < c.length) {
			c[index++] = item;
			return true;
		} else {
			return false;
		}
	}

	// 取元素
	@SuppressWarnings("unchecked")
	public T get(int index) {
		if (index < c.length) {
			return (T) c[index];
		}
		return null;
	}

	// 清空
	public void clear() {
		for (int i = 0; i < c.length; i++) {
			c[i] = null;
		}
		index = 0;
	}

	// 返回下身迭代器
	@Override
	public MyIteratorInf<T> getForwardIterator() {
		return new MyForwardIteratorImpl();
	}

	// 返回逆向迭代器
	@Override
	public MyIteratorInf<T> getReverseIterator() {
		return new MyReverseIteratorImpl();
	}
}

public class IteratorPattern {

	public static void main(String[] args) {
		// 不可以是普通类型,编译器会报:
		// Syntax error, insert "Dimensions" to complete ReferenceType
		// MyQuene<int> q = new MyQuene<int>(10);
		MyQuene<Integer> q = new MyQuene<Integer>(10);

		for (int i = 0; i < 10; i++) {
			q.add(i);
		}
		
		// 检查是否实现了正向迭代器
		// if (q instanceof ForwardIteratorAble<Integer>)
		// 这样不可以,在进行类型检查时不可以包含具体的泛型类型,用“?”代替。
		if (q instanceof ForwardIteratorAble<?>) {
			MyIteratorInf<Integer> iterator = q.getForwardIterator();
			while (iterator.hasNext()) {
				System.out.println(iterator.next());
			}
		}

		// 检查是否实现了逆向迭代器
		MyIteratorInf<Integer> iterator = q.getReverseIterator();
		while (iterator.hasNext()) {
			System.out.println(iterator.next());
		}
	}
}

实现过程:

  1. 定义迭代器接口。
  2. 在容器类内部使用私有内部类实现定义的迭代器接口,只所以使用内部类,是因为内部类能访问外部的容器类的任何成员,包括私有成员。
  3. 在容器类内部定义public方法,new一个迭代器接口的实现并返回。
  4. 定义ForwardIteratorAble与ReverseIteratorAble这两个接口的目的,更主要的其实是起一个标志的作用。容器类可不实现任何迭代器,也可能实现了全部的迭代器。客户在取得迭代器之前通过这个标志,可以动态决断容器类是否实现了某种迭代器。

程序中几个需要注意的地方:

  1. 对于普通类型的数组,如int [] x = new int[5]这样子是不可以的,普通类型的数组不允许这样初始化,类可以。
  2. 集合类的类型参数不可以是普通类型,如果一定要使用普通类型的话应该用相应的封装类代替。
  3. 当判断带有泛型参数的类人类型时,不可以指定明确的泛型参数。如:
    class A<T> {}                                   // 类A是泛型的
    A<Integer> a = new A<Integer>()
    if (a instanceof A<Integer>)             //  不可以,这个与Java泛型的实现机制有关,实际上 A<Integer>这种类型根本就没有存在过。
    应该这样:
    f (a instanceof A<?>)
相关标签: Java 迭代器