【Java设计模式】(1)迭代器模式Iterator

本文通过自定义Java容器类ArrayList和LinkedList,展示了如何利用迭代器模式进行统一的数据遍历操作,实现了面向接口编程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章出处:http://blog.youkuaiyun.com/scarthr/article/details/42371227

我们在最开始接触Java中的容器类List、Map、Collection等就了解到了迭代器Iterator,今天我们就来讲解一下Java中的设计模式之一——迭代器模式。

1. 自己实现List容器

我们先写一个底层用数组实现的自己写的ArrayList容器:

package com.thr.iterator;

public class ArrayList {
	Object[] objects = new Object[10];
	int index = 0;

	public void add(Object o) {
		if (index == objects.length) {
			// 当数组内对象超过数组长度时,将数组的长度扩大2倍
			Object[] newObjects = new Object[objects.length * 2];
			// 将元数组内对象拷贝到新数组中
			System.arraycopy(objects, 0, newObjects, 0, objects.length);
			// 将原数组引用指向新创建的数组
			objects = newObjects;
		}
		objects[index] = o;
		index++;
	}

	public int size() {
		return index;
	}

}

定义一个Person类:

package com.thr.iterator;

public class Person {
	private int age;

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Person(int age) {
		super();
		this.age = age;
	}

	@Override
	public String toString() {
		return "Person [age=" + age + "]";
	}

}
测试一下这个容器:
package com.thr.iterator;

public class Test {

	public static void main(String[] args) {

		ArrayList list = new ArrayList();
		for (int i = 0; i < 15; i++) {
			list.add(new Person(i));
		}
		System.out.println(list.size());
	}

}
可以运行!

然后心情不错,再自己写一个链表结构的LinkedList:

package com.thr.iterator;

public class LinkedList {

	private Node head;
	private Node tail;
	private int size;

	public void add(Object o) {
		Node node = new Node(o, null);
		// 添加元素为第一个时,指定它就是head,同时也是tail。
		if (head == null) {
			head = node;
			tail = node;
		}
		tail.setNode(node);
		tail = node;
		size++;
	}

	public int size() {
		return size;
	}

}
修改测试代码:
package com.thr.iterator;

public class Test {

	public static void main(String[] args) {

		LinkedList list = new LinkedList();
		for (int i = 0; i < 15; i++) {
			list.add(new Person(i));
		}
		System.out.println(list.size());
	}

}

可以运行!

2. 创建Collection接口

这样子写来写去的,它们都含有add方法和size方法,于是我们定义一个接口Collection:

package com.thr.iterator;

public interface Collection {

	public void add(Object o);

	public int size();
}
然后让ArrayList和LinkedList都实现这个接口,这时测试代码成了:

package com.thr.iterator;

public class Test {

	public static void main(String[] args) {

		Collection c = new ArrayList();
		// Collection c = new LinkedList();
		for (int i = 0; i < 15; i++) {
			c.add(new Person(i));
		}
		System.out.println(c.size());
	}

}

以后切换容器的时候只需替换Collection所指向子类的对象即可,这就是所谓的面向接口编程。

3. 迭代器Iterator

那么此时问题就来了,如果需要遍历我们的容器该怎么操作呢?一个是数组的容易,一个是链表的容器,该怎么做呢?

这时候我们就需要定义一个标准出来,让所有的容器都来遵循这个标准就可以。

我们创建一个接口Iterator:

package com.thr.iterator;

public interface Iterator {
	Object next();

	boolean hasNext();
}
在Collection中也定义个iterator方法,返回实现Iterator接口的对象:

package com.thr.iterator;

public interface Collection {

	void add(Object o);

	int size();

	Iterator iterator();
}
修改我们的ArrayList,增加新的方法:

	@Override
	public Iterator iterator() {
		return new ArrayListIterator();
	}

	private class ArrayListIterator implements Iterator {

		private int currentIndex;

		@Override
		public boolean hasNext() {
			boolean flag;
			if (currentIndex >= index) {
				flag = false;
			} else {
				flag = true;
			}
			return flag;
		}

		@Override
		public Object next() {
			Object o = objects[currentIndex];
			currentIndex++;
			return o;
		}
	}
我们定义了一个内部类ArrayListIterator实现了Iterator接口的两个方法,在ArrayList中实现iterator方法,返回了我们的内部类引用。

测试:

		Collection c = new LinkedList();
		// Collection c = new LinkedList();
		for (int i = 0; i < 15; i++) {
			c.add(new Person(i));
		}
		Iterator iterator = c.iterator();
		while (iterator.hasNext()) {
			Object o = iterator.next();
			System.out.println(o + "");
		}
遍历成功!

最后同理修改我们的LinkedList,增加新的接口:

	@Override
	public Iterator iterator() {
		return new LinkedListIterator();
	}

	private class LinkedListIterator implements Iterator {

		private int currentIndex;
		private Node currentNode;

		@Override
		public boolean hasNext() {
			return !(currentIndex >= size);
		}

		@Override
		public Object next() {
			if (currentNode == null) {
				currentNode = head;
			}
			Object o = currentNode.getData();
			currentNode = currentNode.getNode();
			currentIndex++;
			return o;
		}
	}
测试遍历:

		// Collection c = new LinkedList();
		Collection c = new LinkedList();
		for (int i = 0; i < 15; i++) {
			c.add(new Person(i));
		}
		Iterator iterator = c.iterator();
		while (iterator.hasNext()) {
			Object o = iterator.next();
			System.out.println(o + "");
		}
成功!

这么做以来,抽象出来了Collection接口和Iterator接口,让我们以后替换容器类的时候更加的方便,并且在使用Collection做引用时,完全不用考虑各个容器内部是如何实现的,自己在写容器的时候,只需实现规定的接口就可以了。

源码下载


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值