Java--容器(Collection)(二)

三、Iterator–容器中的特殊遍历

  1. 所有实现了Collection接口的容器类都有一个iterator方法用以返回一个实现了Iterator接口的对象;
  2. 作用:Iterator对象作为迭代器,是用来实现遍历操作的;
  3. Iterator接口定义的方法:
    Iterator it = Collection集合对象.iterator();// 获得迭代器
    boolean hashNext();// 判断是否有元素没有被遍历
    Object next();//返回游标当前位置的元素并将游标移动到下一个位置
    void remove();// 删除游标左面的元素,remove()必须紧跟在next()方法后执行,在每次调用next()时,remove方法只能被调用一次。
    4 . 分析
    Iterator iterator();定义一个引用类型(接口类型)的变量it来“接收”返回的Iterator
    A.Iterator仅用于遍历集合,其本身并不能提供盛装对象的能力
    B. List和Set都有iterator()来取得其迭代器。对List来说,你也可以通过listIterator()取得其迭代器,两种迭代器在有些时候是不能通用的,Iterator和ListIterator主要区别在以下方面:
    a. ListIterator有add()方法,可以向List中添加对象,而Iterator不能
    b. ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历,但是 ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator就不可以。
    c.ListIterator可以定位当前的索引位置,nextIndex()和previousIndex()可以实现。Iterator没有此功能。
    d. 都可实现删除对象,但是ListIterator可以实现对象的修改,set()方法可以实现。Iierator仅能遍历,不能修改。
public class TestIterator {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");

        for (int i = 0; i < list.size(); i ++){
            System.out.println((String)list.get(i));
        }

        Set set = new HashSet();
        set.add("1");
        set.add("2");
        set.add("3");


        // 迭代器iterator遍历set
        Iterator ite =  set.iterator();// iterator迭代器:Iterator it = 实现Collectio接口的对象.iterator;
        while (ite.hasNext()){
            System.out.println((String)ite.next());
            // ite.remove();
        } 

    }   
}

public class TestListIterator {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("aa");
        list.add("bb");
        list.add("cc");
        list.add("dd");

        ListIterator it = list.listIterator(list.size());
        while (it.hasPrevious()){// 逆向遍历
            it.previous();
        }
    }
}

5 .关于Java中的增强for循环
增强for的效率高,是因为直接操作硬盘,实际也是迭代器。区别是增强for没有删除,迭代器有,而且是在查看的时候就可以删除。

MyArrayList:
/**
 * 深入理解迭代器原理
 * 模拟迭代器的三个常用方法
 * @author Fanff
 *
 */
public class MyArrayList {
    private String[] elem = {"a", "b", "c", "d", "e", "f", "g"};
    private int size = elem.length;
    private int cursor = 0;// 游标,ArrayList中是置为的0,其他有些地方是-1

    /**
     * 判断是否还存在下一个元素
     */
    public boolean hasNext(){
        return cursor < size;
    }
    /**
     * 返回游标所指的当前位置的元素,并将游标移到下一个位置
     */
    public String next(){
        String e = elem[cursor];
        cursor++;
        return e;
    }
    /**
     * 删除游标所指位置的元素
     */
    public void remove(){}

    public static void main(String[] args) {
        MyArrayList list = new MyArrayList();
        while (list.hasNext()){
            System.out.println(list.next());
        }
    }
}
MyArrayList1:

import java.util.Iterator;
/**
 * 深入理解迭代器原理
 * 自定义迭代器:实现Iterator接口
 * 将迭代器中的三个常用方法封装成内部类,以减少开销
 * @author Fanff
 *
 */
public class MyArrayList1 {
    private String[] elem = {"a", "b", "c", "d", "e", "f", "g"};
    private int size = elem.length;

    private class MyImpIterator implements Iterator<String>{
        private int cursor = 0;// 游标,ArrayList中是置为的0,其他有些地方是-1

        /**
         * 判断是否还存在下一个元素
         */
        public boolean hasNext(){
            return cursor < size;
        }
        /**
         * 返回游标所指的当前位置的元素,并将游标移到下一个位置
         */
        public String next(){
            String e = elem[cursor];
            cursor++;
            return e;
        }
        /**
         * 删除游标所指位置的元素
         */
        public void remove(){}
    }

    public Iterator<String> myIterator(){
        return new MyImpIterator();
    }

    public static void main(String[] args) {
        MyArrayList1 list = new MyArrayList1();
        Iterator<String> it = list.myIterator();
        while (it.hasNext()){
            System.out.println(it.next());
        }

        // 如果要再遍历一次只需要通过myIterator()方法new一个MyImpIterator()
        // 而不需要new一个MyArrayList1()对象,减小了开销
        Iterator<String> it1 = list.myIterator();
        while (it1.hasNext()){
            System.out.println(it1.next());
        }
    }
}

MyArrayList2:
import java.util.Iterator;
/**
 * 深入理解迭代器原理:
 * 理解增强for循环的本质
 *使用增强for循环,必须是遍历的数组,或者是实现了Iterable接口
 * @author Fanff
 * 
 */
public class MyArrayList2 implements Iterable<String>{
    private String[] elem = { "a", "b", "c", "d", "e", "f", "g" };
    private int size = elem.length;

    // 匿名内部类
    @Override
    public Iterator<String> iterator() {
        return new Iterator<String>() {
            private int cursor = 0;// 游标,ArrayList中是置为的0,其他有些地方是-1

            /**
             * 判断是否还存在下一个元素
             */
            public boolean hasNext() {
                return cursor < size;
            }

            /**
             * 返回游标所指的当前位置的元素,并将游标移到下一个位置
             */
            public String next() {
                String e = elem[cursor];
                cursor++;
                return e;
            }

            /**
             * 删除游标所指位置的元素
             */
            public void remove() {
            }
        };
    }

    public static void main(String[] args) {
        MyArrayList2 list = new MyArrayList2();
        Iterator<String> it = list.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
        System.out.println("-----增强for循环的效率更高是因为实际上其是利用的迭代器-----");
        // 使用增强for循环,必须是遍历的数组,货值是实现了Iterable接口
        for (String temp : list){
            System.out.println(temp);
        }

    }
}

说明:
(1). 查看jdk可知Iterable和Iterator都是接口,但Iterable中只有一个返回Iterator对象的方法;
(2). Iterable和Iterator的区别(http://blog.csdn.net/ningguixin/article/details/8079242):
很多类(尤其是一些集合类)都实现了Iterable接口,这样就可以通过实现Iterable接口里唯一的的方法Iterator iterator();返回一个Iterator对象,进而实现Itrator接口中的三个常用方法,从而调用这三个常用方法。HashSet类就实现了Iterable接口,而要访问或打印出Set中所有内容时,就是利用的Iterator对象(实例如下)【Iterator it = 实现Collectio接口的对象.iterator;】
(3). 为什么一定要实现Iterable接口,为什么不直接实现Iterator接口呢?
JDK中的集合类,比如List一族或者Set一族,都是实现了Iterable接口,但并不直接实现Iterator接口。
原因: 因为Iterator接口的核心方法next()或者hasNext() 是依赖于迭代器的当前迭代位置的。如果Collection直接实现Iterator接口,那么势必导致集合对象中包含当前迭代位置的数据(指针)。当集合在不同方法间被传递时,由于当前迭代位置不可预置,那么next()方法的结果会变成不可预知。除非再为Iterator接口添加一个reset()方法,用来重置当前迭代位置。
但即时这样,Collection也只能同时存在一个当前迭代位置。 而Iterable则不然,每次调用都会返回一个从头开始计数的迭代器。 多个迭代器是互不干扰的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值