1. 迭代器模式测试 == 典型的类似集合的方式实现了我们自己的迭代器,通过迭代器实现元素的遍历
package com.zhaoshuangjian.mode16_迭代器模式;
import com.zhaoshuangjian.mode16_迭代器模式.mode16.AbstractAggregate;
import com.zhaoshuangjian.mode16_迭代器模式.mode16.IIterator;
import com.zhaoshuangjian.mode16_迭代器模式.mode16.MyCollection;
/**
* <p>迭代器模式测试 == 典型的类似集合的方式实现了我们自己的迭代器,通过迭代器实现元素的遍历</p>
*
* @Author zhaoshuangjian 2023-03-25 下午21:44
*/
public class IteratorTest {
public static void main(String[] args) {
myIterator();
}
private static void myIterator(){
Integer[] numArr = new Integer[]{1,2,3};
AbstractAggregate aggregate = new MyCollection(numArr);
IIterator iterator = aggregate.createIterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("==============若想要迭代器继续迭代输出元素");
System.out.println("first = " +iterator.first());
System.out.println("==============我们可以调用first方法重置pos");
while (iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("==============我们再来创建一个迭代器对象出来");
IIterator iteratorOther = aggregate.createIterator();
while (iteratorOther.hasNext()){
System.out.println(iteratorOther.next());
}
}
/**
* <p>资料如此描述迭代器模式:</p>
* 迭代器模式又叫游标模式,是对象的行为模式。
* 迭代器模式可以顺序的访问一个聚集中的元素而不必暴露聚集内部表象。
*
* 什么意思呢,博主来白话一下:
* (1)这是对对象的操作,因此属于对象的行为操作范畴
* (2)聚集对象可以进行元素的遍历,既然是遍历,肯定要讲究顺序的(pos++)
* (3)使用者知道怎么遍历取出元素就行,具体聚合类是怎么实现的,
* 不告诉你,反正你给我传一个数组就行,我给你创建一个迭代器出来,
* 具体怎么玩,你拿着我给你创建好的迭代器琢磨去吧!
*
* 优点:
* (1)本来聚集类要干的事情,分担给具体的迭代器类了,聚集类和迭代器实现了很好的解耦,
* 这样一来,迭代的算法可以完全独立于聚集类;
* (2)一个聚集类的对象,也就是聚集对象,可以创建出N个迭代器,同时进行元素迭代而互不干扰
*/
}
2. 抽象出来一个聚集类 == 提供创建集合对象迭代器的一系列抽象方法
package com.zhaoshuangjian.mode16_迭代器模式.mode16;
/**
* <p>抽象出来一个聚集类 == 提供创建集合对象迭代器的一系列抽象方法</p>
*
* @Author zhaoshuangjian 2023-03-25 下午21:44
*/
public abstract class AbstractAggregate {
/**
* <p>创建聚集对象的迭代器 == 使用迭代器对集合进行相关操作</p>
* @return 对象的迭代器
*/
public abstract com.zhaoshuangjian.mode16_迭代器模式.mode16.IIterator createIterator();
/**
* <p>返回聚集对象(集合、迭代器对象)包含的对象(元素)的大小</p>
* @return 大小
*/
public abstract int size();
/**
* <p>聚集对象包含的元素是否为空</p>
* @return 空(true)不空(false)
*/
public abstract boolean isEmpty();
}
3.迭代器接口
package com.zhaoshuangjian.mode16_迭代器模式.mode16;
/**
* <p>迭代器接口</p>
*
* @Author zhaoshuangjian 2023-03-25 下午21:44
*/
public interface IIterator {
/**
* <p>当前迭代器中是否还有元素</p>
* @return 有(true) 没有(false)
*/
boolean hasNext();
/**
* <p>取出迭代器中的元素</p>
* @return 对象
*/
Object next();
/**
* <p>取出迭代器中的第一个元素</p>
* @return 第一个元素
*/
Object first();
}
4.自定义集合类,实现聚集抽象类中的迭代器的创建方法
package com.zhaoshuangjian.mode16_迭代器模式.mode16;
/**
* <p>自定义集合类,实现聚集抽象类中的迭代器的创建方法</p>
*
* @Author zhaoshuangjian 2023-03-25 下午21:44
*/
public class MyCollection extends com.zhaoshuangjian.mode16_迭代器模式.mode16.AbstractAggregate {
/**
* 集合的底层用的就是数组
*/
Object[] objArr ;
public MyCollection(Object[] objArr){
this.objArr = objArr;
}
@Override
public com.zhaoshuangjian.mode16_迭代器模式.mode16.IIterator createIterator() {
/**
* 将当前集合对象作为参数,调用迭代器的构造函数
* 注意,该方法的NB之处,就是同一个聚集对象可以new出来好多个迭代器
* 虽然,上面一段话说出来跟没说一样,但是博主还是想傻傻的强调一下
*/
return new MyIterator(this);
}
@Override
public int size() throws NullPointerException{
if(objArr == null){
throw new NullPointerException("objArr is null !");
}
return objArr.length;
}
@Override
public boolean isEmpty() throws NullPointerException{
if(objArr == null){
throw new NullPointerException("objArr is null !");
}
return objArr.length == 0 ;
}
public Object[] getObjArr() {
return objArr;
}
public void setObjArr(Object[] objArr) {
this.objArr = objArr;
}
}
5.自定义迭代器,实现迭代器接口中的所有方法
package com.zhaoshuangjian.mode16_迭代器模式.mode16;
/**
* <p>自定义迭代器,实现迭代器接口中的所有方法</p>
*
* @Author zhaoshuangjian 2023-03-25 下午21:44
*/
public class MyIterator implements com.zhaoshuangjian.mode16_迭代器模式.mode16.IIterator {
/**
* 迭代器的目标对象,就是集合
*/
private com.zhaoshuangjian.mode16_迭代器模式.mode16.MyCollection collection ;
/**
* 这里保留一份集合对象包含的元素的大小
*/
private int size ;
/**
* 记录元素的位置
*/
private int pos = 0 ;
public MyIterator(com.zhaoshuangjian.mode16_迭代器模式.mode16.MyCollection collection){
this.collection = collection ;
this.size = collection.size();
}
@Override
public boolean hasNext() {
/**
* (1)只要size不等于pos初始化时候的0,集合里肯定是有元素的
* (2)返回true的时候,一定不要忘了让pos往后移,这就是迭代器只能使用一次的原因所在
* (3)如果想复用迭代器,调用first函数,重置pos位置的值
*/
if(pos < size){
pos++;
return true;
}
return false;
}
@Override
public Object next() {
return collection.getObjArr()[pos-1];
}
@Override
public Object first() {
pos = 0;
return collection.getObjArr()[0];
}
}