Java中迭代器的使用
由于Java中数据容器众多,而对数据容器的操作在很多时候都具有极大的共性,于是Java采用了迭代器为各种容器提供公共的操作接口------说明与具体的数据结构无关。
使用Java的迭代器iterator可以使得对容器的遍历操作完全与其底层相隔离,可以到达极好的解耦效果。
public interface Iterable<T>
Iterator<T>
iterator()
Returns an iterator over a set of elements of type T
Collection接口拓展了接口Iterable,根据以上的对Iterable接口的定义可以发现,其要求实现其的类都提供一个返回迭代器Iterator<T>对象的方法。
迭代器Iterator<T>接口的的定义为:
Interface Iterator<E>
Iterator的三个方法:
boolean
hasNext()
Returns true if the iteration has more elements.E
next()
Returns the next element in the iteration.void
remove()
Removes from the underlying collection the last element returned by the iterator (optional operation).注意:
从以上的定义中可以发现,似乎Iterable()接口和Iterator()接口完全一致,没有任何区别。结合刚刚学习的内部类,可以发现这又是一个支持程序多样化的巧妙设计,充分的支持了多态和解耦。
1、由于所有的Collection类型的对象都被强制要求implements Iterable 接口,故任何Collection对象都要能返回一个能遍历其的迭代器Iterator。如果直接 implement iterator接口, Collection会直接要求具有hasNext()等方法。但是这种方法不具备多态性,即设定好了该如何执行hasNext()等操作,而且程序会显得十分的臃肿和复杂。但是如果采用实施Iterable()接口和返回Iterator对象的方式,则会全然的不同,只要能够返回Iterator对象,完全可以自己的需要进行遍历方式上的自由定义。(即针对同一个接口,在其实现类中提供多样、不同的方法)。
Example:
public class TestIterable { TestIterable(){ ScanAppleStore appleTree= new ScanAppleStore(); print("Try normal iterator:"); for(String str:appleTree) { print(str); } print("Try reverse iterator:"); for(String str:appleTree.reverseIterator()) { print(str); } } } class ScanAppleStore implements Iterable<String> { ArrayList<String> appleStore = new ArrayList<String>(); ScanAppleStore() { Collections.addAll(appleStore,"Sweet","Sour","Bitter","litter Sweet","litter Sour","litter Bitter"); print(appleStore); } public Iterator<String> iterator() { return new Iterator<String>(){ private int i=0; public boolean hasNext() { if(i<appleStore.size()) { return true; } else { return false; } } public String next() { return appleStore.get(i++); } public void remove() { print("not defined!"); } }; } public Iterable<String> reverseIterator() { return new Iterable<String>() { public Iterator<String> iterator(){ return new Iterator<String>(){ private int i=appleStore.size()-1; public boolean hasNext() { if(i>-1) { return true; } else { return false; } } public String next() { return appleStore.get(i--); } public void remove() { print("not defined!"); } }; } }; } }
从以上的例子中可以发现,为了实现对ScanAppleStore类对象的遍历,共定义了两种迭代器供选择:
1、public Iterator<String> iterator() :该迭代器被定义为ScanAppleStore implements Iterable接口的方法, 采用常规的顺序遍历方式,for(String str:appleTree) 时自动被转型调用。
2、public Iterable<String> reverseIterator():该迭代器采用了匿名内部类的方式实现Iterable接口,并返回Iterable对象,采用逆序的遍历方式,for(String str:appleTree.reverseIterator())时,通过调用appleTree.reverseIterator()方法返回Iterable对象。
!foreach语法的标准形式为:for(T element : Iterable<T> elements)
由于Iterable接口要求实现iterator()方法,iterator()方法要求返回Iterator对象,Iterator定义了hasNext(), next(), remove()三种必须被实现的方法。
故实现Iterable的稍显拖沓和复杂:
Example:
<span>public Iterable<String> reverseIterator() { return new Iterable<String>() { public Iterator<String> iterator(){ return new Iterator<String>(){</span> private int i=appleStore.size()-1; public boolean hasNext() { if(i>-1) { return true; } else { return false; } } public String next() { return appleStore.get(i--); } public void remove() { print("not defined!"); } }; } }; } }
此处采用了匿名内部类的方式,结构十分的清晰,此处更是体现出了内部类对于实现接口,强化OOP Java编程能力的重要性。
注意Iterable<T>中强调使用范型,故在定义的时候一定要注意指明类型。
迭代器接口要求实现其的类必须提供三种方法:
hasNext()
:遍历过程中,判定是否还有下一个元素。(从Collection对象的第一个元素开始)
next()
: 遍历该元素。(即取出下一个元素)remove(): 移除刚刚遍历过的元素。
从定义可以发现,该三个方法经常是被搭配使用的。
Examle:
Iteraotr it= arrayList.Iterator();
while(it.hasNext())
{
print(it.next());
it.remove();
}
基本思路为:在遍历下一个元素前,先判断其是否存在。对于想删除的元素,必须先遍历其,故 remove()方法总是接在 next()方法之后。
注:本文来源:http://www.cnblogs.com/airwindow/archive/2012/06/25/2560811.html
初学hadoop程序之---------------Iterable<T>迭代器
最新推荐文章于 2022-12-07 15:48:32 发布