迭代器Iterator的简单实现

本文介绍了Java中如何使用Iterator迭代器遍历Collection接口的子类容器。通过迭代器的三个核心方法,实现对容器内部元素的访问。同时,讨论了迭代器的改进方案,包括将迭代器作为局部内部类来提高代码的封装性。

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

一、一个简单使用 Iterator 迭代器的代码

 List list= new ArrayList();
 list.add("aaa");
 list.add("bbb");
 list.add("ccc");
 //(1)通过循环遍历List
 for(int i=0;i<list.size();i++){
    System.out.println(list.get(i));
 }
 //(2)通过迭代器遍历List
 for(Iterator it= list.iterator(); it.hasNext(); ){
    String str = (String) it.next();
    System.out.println(str);
 }


二、理解 Iterator 的内部原理

1、所有实现了Collection接口的容器类,都有一个iterator方法,用以返回一个实现了Iterator接口的对象。
2、Iterator对象称作 迭代器 ,用以方便的实现对容器内部元素的遍历操作。
3、Iterator接口定义了如下方法:

boolean hasNext();    判断是否有元素没有被遍历
Object next();    返回游标当前位置的元素,并将游标移动到下一个位置
void remove();    删除游标左面的元素(刚刚遍历完的那个元素),在执行完next之后该操作只能执行一次


4、几种实现方法(逐渐改进...)

(1)简单实现迭代器的三大函数

public class IteratorImp {
       private String[] elem={"a","b","c","d"};
       private int size = elem.length;
       
       
       public int size(){
              return size;
       }
       
       //计数器:指针、游标, 指向当前访问过的元素
       private int coursor = -1;
       
       //判断是否存在下一个
       public boolean hasNext(){
              return (coursor+1)<size;
       }
       
       //获取下一个
       public Object next(){
              coursor++;
              return elem[coursor];
       }
       
       //删除下一个
       public void remove(){
              //移动数组的元素
              System.arraycopy(elem, coursor+1, elem, coursor, size-coursor-1);
              this.size--;
              //退回上一个访问的元素,即可实现多次删除
              this.coursor--;
       }
       
       public static void main(String[] args) {
              // TODO Auto-generated method stub
              IteratorImp it =new IteratorImp();
              while(it.hasNext()){
                     System.out.println((String) it.next());
              }
              System.out.println("总共有"+it.size()+"个元素!");
       }
}

(2)改进版1:将这三个方法封装在一个非静态内部类中,作为迭代器对的实现

public class IteratorImp {
       private String[] elem={"a","b","c","d"};
       private int size = elem.length;
             
       public int size(){
              return size;
       }     
       //私有,非静态内部类
       private class myIterator implements Iterator{   
              //计数器:指针、游标, 指向当前访问过的元素
              private int coursor = -1;
              //判断是否存在下一个
              public boolean hasNext(){
                     return (coursor+1)<size;
              }
              //获取下一个
              public Object next(){
                     coursor++;
                     return elem[coursor];
              }
              //删除下一个
              public void remove(){
                     //移动数组的元素
                     System.arraycopy(elem, coursor+1, elem, coursor, size-coursor-1);
                     size--;
                     //退回上一个访问的元素,即可实现多次删除
                     this.coursor--;
              }
       }  
     
       public Iterator iterator(){
              return new myIterator();
       }
       
       public static void main(String[] args) {
              IteratorImp list = new IteratorImp();
              Iterator it = list.iterator();
              while(it.hasNext()){
                     System.out.println(it.next());
              }
       }
}

(3)改进版2:由于该迭代器对象只在iterator方法中用到了,所以可以把它改成iterator方法中的局部内部类。

public class IteratorImp {
       private String[] elem={"a","b","c","d"};
       private int size = elem.length;
       
       
       public int size(){
              return size;
       }
       public Iterator iterator(){
              
              //局部内部类:定义在方法里的类,仅在该方法中有效。他不属于外部类,因此不能用访问控制符和static修饰
              class myIterator implements Iterator{    
                     //计数器:指针、游标, 指向当前访问过的元素
                     private int coursor = -1;
                     //判断是否存在下一个
                     public boolean hasNext(){
                           return (coursor+1)<size;
                     }
                     //获取下一个
                     public Object next(){
                           coursor++;
                           return elem[coursor];
                     }
                     //删除下一个
                     public void remove(){
                           //移动数组的元素
                           System.arraycopy(elem, coursor+1, elem, coursor, size-coursor-1);
                           size--;
                           //退回上一个访问的元素,即可实现多次删除
                           this.coursor--;
                     }
              }
              return new myIterator();
       } 
     
       public static void main(String[] args) {
              IteratorImp list = new IteratorImp();
              Iterator it = list.iterator();
              while(it.hasNext()){
                     System.out.println(it.next());
              }
       }
}

(4)改进版3:由于Iterator接口的实现类myIterator在程序中只是用了一次,因此可以进一步改成匿名内部类。

public class IteratorImp {

	private String[] elem={"a","b","c","d"};
	private int size = elem.length;
	
	
	public int size(){
		return size;
	}

	public Iterator iterator(){
		
		return new Iterator(){  //创建Iterator迭代器接口的实现类(没有名称)的对象
			//计数器:指针、游标, 指向当前访问过的元素
			private int coursor = -1;

			//判断是否存在下一个
			public boolean hasNext(){
				return (coursor+1)<size;
			}
			//获取下一个
			public Object next(){
				coursor++;
				return elem[coursor];
			}
			//删除下一个
			public void remove(){
				//移动数组的元素
				System.arraycopy(elem, coursor+1, elem, coursor, size-coursor-1);
				size--;
				//退回上一个访问的元素,即可实现多次删除
				this.coursor--;
			}
		};
	}
	
	public static void main(String[] args) {
		IteratorImp list = new IteratorImp();
		Iterator it = list.iterator();
		while(it.hasNext()){
			System.out.println(it.next());
		}
	}

}


(5)改进版4:

前面4种实现方法中,均在String数组已知的条件下,进行遍历的。
我们实现一个可以向字符串数组中添加删除元素的类,相当于一个String集合。并实现使用foreach对集合元素进行遍历。
/**
 * 目标:深入迭代器原理 --> 一个容器可以创建多个迭代器对象
 * 
 * 深入
 * 1、使用内部类实现迭代器
 * 2、继承接口java.lang.Iterable,实现foreach循环迭代访问集合元素
 * 3、加入末尾添加元素的方法add()
 * @author Administrator
 *
 */

public class StringCollection implements java.lang.Iterable {

	private String[] elem= new String[5];
	private int size;
	
	
	public int size(){
		return this.size;
	}

	public boolean add(String s){
		if(this.size==elem.length){
			//String数组容量不够了,就扩容
			elem=Arrays.copyOf(elem, elem.length+5);
		}
		elem[size++]=s;
		return true;
	}
	
	/*	 ...其他方法get、remove、clear等方法就不再赘述了...	 */
	
	public Iterator iterator(){
		
		return new Iterator(){  //创建Iterator迭代器接口的实现类(没有名称)的对象
			//计数器:指针、游标, 指向当前访问过的元素
			private int coursor = -1;

			//判断是否存在下一个
			public boolean hasNext(){
				return (coursor+1)<size;
			}
			//获取下一个
			public Object next(){
				coursor++;
				return elem[coursor];
			}
			//删除下一个
			public void remove(){
				//移动数组的元素
				System.arraycopy(elem, coursor+1, elem, coursor, size-coursor-1);
				size--;
				//退回上一个访问的元素,即可实现多次删除
				this.coursor--;
			}
		};
	}
	
	public static void main(String[] args) {
		StringCollection s = new StringCollection();
		s.add("111");
		s.add("222");
		s.add("222");
		s.add("222");
		s.add("222");
		s.add("222");
		s.add("222");
		System.out.println(s.size());
		
		//使用Java 5  提供的 foreach 循环迭代访问集合元素
		List list1 = new ArrayList();
		list1.add("123");
		list1.add("222");
		list1.add(s);
		for(Object obj:list1){
			System.out.println(obj);
		}
		
		//如果迭代访问我们创建的StringCollection集合的元素,可以吗?
		//会提示错误:an only iterate over an array or an instance of java.lang.Iterable
		//因此,只需要在类定义时继承接口java.lang.Iterable即可
		for(Object obj:s){
			System.out.println((String)obj);
		}
	}
}
7
123
222
com.yuan.Iterator.StringCollection@515632d
111
222
222
222
222
222
222



(6)使用泛型
/**
 * 目标:使用泛型,可以操纵多个类型
 *
 */

public class ArrayList007<E> implements java.lang.Iterable {

	private Object[] elem= new Object[5];//泛型没有数组,因此使用Object数组
	private int size;
	
	
	public int size(){
		return this.size;
	}

	public boolean add(E ele){
		if(this.size==elem.length){
			//String数组容量不够了,就扩容
			elem=Arrays.copyOf(elem, elem.length+5);
		}
		elem[size++]=ele;
		return true;
	}
	
	/*	 ...其他方法get、remove、clear等方法就不再赘述了...	 */
	
	public Iterator<E> iterator(){
		
		return new Iterator<E>(){  //创建Iterator迭代器接口的实现类(没有名称)的对象
			//计数器:指针、游标, 指向当前访问过的元素
			private int coursor = -1;

			//判断是否存在下一个
			public boolean hasNext(){
				return (coursor+1)<size;
			}
			//获取下一个
			public E next(){
				coursor++;
				return (E) elem[coursor];
			}
			//删除下一个
			public void remove(){
				//移动数组的元素
				System.arraycopy(elem, coursor+1, elem, coursor, size-coursor-1);
				size--;
				//退回上一个访问的元素,即可实现多次删除
				this.coursor--;
			}
		};
	}
	
	public static void main(String[] args) {
		ArrayList007<String> s = new ArrayList007<String>();
		s.add("111");
		s.add("222");
		s.add("222");
		//System.out.println(s.size());
		Iterator<String> it = s.iterator();
		while(it.hasNext()){
			System.out.println(it.next());
		}
		
		ArrayList007<Integer> s2 = new ArrayList007<Integer>();
		s2.add(1);  //int-->Integer自动装箱
		s2.add(2);
		for(Object i:s2){
			System.out.println(i);
		}
	}
}
111
222
222
1
2






















                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值