迭代器详解与适配迭代器

轻量级对象

迭代器是一个对象,用于遍历并选择序列中的对象,直接使用迭代器,迭代器不需要考虑容器内部的类型信息,也不需要关心不同容器的底层原理和性质。
迭代器被称为轻量级对象,功能简单有限:1、只能使用iterator()返回容器的迭代器,2、next(),3、hasNext(),4、remove()删除迭代器新近的返回元素。

程序示例展示了利用Iterator不需要确定容器中的类型信息,也不需要关心Collection的类型。

class SimpleIterator{
    public static void display(Iterator it){
        while(it.hasNext()){
            System.out.print(it.next()+" ");
        }
        while(it.hasNext()){
            it.next();
            it.remove();
        }
    }
    public static void main(String[] args) {
        Integer[] integers=new Integer[]{
                1,2,3,4
        };
        ArrayList<Integer> arrayList =new ArrayList<Integer>(Arrays.asList(integers));
        LinkedList<Integer> linkedList=new LinkedList<Integer>(Arrays.asList(integers));
        TreeSet<Integer> treeSet=new TreeSet<Integer>(Arrays.asList(integers));
        HashSet<Integer> hashSet=new HashSet<Integer>(Arrays.asList(integers));
        display(arrayList.iterator());
        display(linkedList.iterator());
        display(treeSet.iterator());
        display(hashSet.iterator());
    }
}

ListIterator
ListIterator是一个Iterator的子类。

class SimpleListIterator{
    public static void main(String[] args) {
        List<Integer> list=new ArrayList<Integer>(Arrays.asList(1,2,3,4));
        System.out.println(list);

        ListIterator it=list.listIterator();

        while(it.hasNext()) {
            System.out.print(it.next()+" "+it.nextIndex()+" ");
        }
        System.out.println();
        while (it.hasPrevious()){
            System.out.print(it.previous()+" "+it.previousIndex()+" ");
        }
    }
}
//output:
//[1, 2, 3, 4]
//1 1 2 2 3 3 4 4
//4 2 3 1 2 0 1 -1

Entry
大量的类都是Iterator类型,主要包括Collection,但是Map并非Iterable,它用Entry表示一对键值。
程序示例用于打印环境变量

class EntryTest{
    public static void main(String[] args) {
        for(Map.Entry entry:System.getenv().entrySet())
            System.out.println(entry);
    }
}
Foreach与迭代器

foreach使用Iterable接口移动。Foreach语句之所以能够用于Collection,是因为Collection继承了Iterable接口,所以要想创建在foreach语句中的类需要继承Iterable接口。C++里通过直接传入Iterator是不是直观又简单。

class IteratorClass implements Iterable<String>{
    private String[] words="hello world".split(" ");

    @Override
    public Iterator<String> iterator() {
        return new Iterator<String>() {
            private int index=0;
            public boolean hasNext() {
                return index<words.length;
            }

            public String next() {
                return words[index++];
            }

            public void remove() {
                throw new UnsupportedOperationException();
            }
        };
    }

    public static void main(String[] args) {
        for(String s:new IteratorClass())
            System.out.println(s);
    }
}
//output:
//hello
//world
适配迭代器

我们知道除了list中的Iterator可以双向移动之外,只能前向移动,若想要迭代器产生其他行为就有需要建立其他迭代器,通常做法是给定不同迭代器不同的名字,不然就会覆盖。
程序示例1是我初始的想法,只可以实现Iterator,但是没办法使用foreach语句,foreach语句是使用Ierable接口遍历。
foreach使用Iterable,Iterable应该是想说某个类具有某种迭代的能力,不同迭代的能力产生不同迭代方式,每种能力自己有相应的迭代器。所以我在示例1中使用了reversedIterator()表明是一反向迭代器,示例2中使用reverse()表明是一种能力。
而且foreach语句内部是使用Iterator()方法返回对应的Iterator从而进行操作的(回调——策略设计模式),应该是为了简化利用foreach语句的代价——直接继承接口。

//示例1
class ReversedArray<T> extends ArrayList<T>{
    Iterator<T> reversedIterator(){
        return new Iterator<T>() {
            private int index=size()-1;
            public boolean hasNext() {
                return index>-1;
            }

            public T next() {
                return get(index--);
            }
        };
    }
}
class Test{
    public static void main(String[] args) {
        ReversedArray<Integer> array=new ReversedArray<Integer>();
        array.addAll(Arrays.asList(1,2,3,4));

// Error:  for(Integer integer:array.reversedIterator())
//         System.out.println(integer);
    }
}
//示例1
class ReversedArray<T> extends ArrayList<T>{
    Iterable<T> reverse(){
        return new Iterable<T>() {
            @Override
            public Iterator<T> iterator() {
                return new Iterator<T>() {
                    private int index=size()-1;

                    public boolean hasNext() {
                        return index>-1;
                    }
                    public T next() {
                        return get(index--);
                    }
                };
            }
        };
    }
}
class Test{
    public static void main(String[] args) {
        ReversedArray<Integer> array=new ReversedArray<Integer>();
        array.addAll(Arrays.asList(1,2,3,4));

        for(Integer integer:array.reverse)
            System.out.println(integer);
    }
}
//output:
//4
//3
//2
//1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值