我们希望在默认的前向迭代器的基础上,添加反向迭代器能力。(迭代器要适用于foreach语句中)
具体思路:所有实现了iterable接口的类都能够被用于foreach语句中。
要想实现双向迭代器的功能,首先可以声明一个类(ReversibleArrayList)继承ArrayList,使用ArrayList里面自带的正向迭代器,在ResersibleArrayList里面使用一个方法来实现反向迭代功能。
因为迭代器是要被放在foreach语句中的,所以这个方法返回的类型应该是一个Iterable的子类。这里就可以使用到匿名内部类,并且重写这个Iterable子类的iterator()方法,使其返回的Iterator的迭代方式是反向的。(这里就体现了java中通过内部类来弥补没有多继承的缺陷。ReversibleArrayList继承了ArrayList类,这样就可以使用ArrayList的正向迭代器,其内部reversed()方法又创建了一个实现了Iterable接口的匿名内部类,这个内部类实现了反向迭代的作用)
具体代码如下:
package p434;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class ReversibleArrayList<M> extends ArrayList<M>{
public ReversibleArrayList(Collection<M> c){super(c);}
public Iterable<M> reversed(){
return new Iterable<M>(){
@Override
public Iterator<M> iterator() {
// TODO Auto-generated method stub
return new Iterator<M>(){
private int current=size()-1;
@Override
public boolean hasNext() {
// TODO Auto-generated method stub
return current>-1;
}
@Override
public M next() {
// TODO Auto-generated method stub
return get(current--);
}
};
}
};
}
}
package p434;
import java.util.Arrays;
public class AdapterMethodIdiom {
public static void main(String[] args) {
ReversibleArrayList<String> re =new ReversibleArrayList<String>(
Arrays.asList("I love you".split(" ")));
for(String s :re){
System.out.println(s+" ");
}
for(String s :re.reversed()){
System.out.println(s+" ");
}
}
}
反思:在匿名内部类的hasNext()方法中,我错误的以为返回值应该是current>0;事实上,迭代器中hasNext()返回的是当前元素是否为空。(next(), 是返回当前元素, 并指向下一个元素。hasNext(), 则是判断当前元素是否存在,并指向下一个元素(即所谓的索引))
在继承ArrayList<T>中最开始遗漏携程了public class ReversibleArrayList<T> extends ArrayList,结果在foreach语句中
给我re报错,说是不能讲Object转化为String,错误信息为:
“Type mismatch: cannot convert from element type Object to String”
因此个人猜想倘若不标识“<>”内的内容,则默认该持有对象持有的为Object对象,在“<>”内加入了变量,则根据实际创建的时候内容表示对象里面持有的对象为什么类型(这一点类似于函数的形参)。