Java中list集合遍历

目录

遍历的3种方式

方式1:迭代器循环

Iterator迭代器

功能:

注意事项:

方法:

ListIterator迭代器

功能:

注意:

方法:

方式2:增强for循环

方式3:普通for循环


遍历的3种方式

        1,迭代器循环

        2,增强for循环

        3,普通for循环

方式1:迭代器循环

迭代器创建后,最好立即使用,不然之后对集合进行的增删改操作会导致迭代器遍历报错

原因:

        1,系统创建迭代器时,会初始化 字段  expectedModCount = modCount,迭代器遍历获取字段时,next()会先对该字段进行校验

        2, 对集合进行的  任何增删 操作都会导致  modCount++,从而在迭代器遍历时,在expectedModCount == modCount  中返回false,导致报错

private class Itr implements Iterator<E> {
    int cursor;       // index of next element to return
    int lastRet = -1; // index of last element returned; -1 if no such
    int expectedModCount = modCount;    //初始化  expectedModCount 字段

    public E next() {
        //获取下个元素时 , 会先对字段  expectedModCount == modCount  进行校验
        checkForComodification();
        ....
    }

    final void checkForComodification() {
        if (modCount != expectedModCount)    //  不相等,会报错
            throw new ConcurrentModificationException();
    }
}            

Iterator迭代器

功能:

        1,单向遍历

        2,遍历过程中,不能增加和修改元素

        3,遍历过程中,只能使用  Iterator提供的remove()  删除元素,不能使用Collection.remove()  删除元素

注意事项:

           删除元素前,需要先调用next(),否则会报错

           因为remove()中,更新 lastRet=-1,而要调用remove(),会先校验lastRet<0,抛异常

范例:

        Collection<Student> c = new ArrayList<Student>();
        Student s1 = new Student("zhang", 12);
        Student s2 = new Student("lsii", 23);
        Student s3 = new Student("wangwu", 24);
        Student s4 = new Student("zhoaliu", 24);

        c.add(s1);
        c.add(s2);
        c.add(s3);
        c.add(s4);

        Iterator<Student> itStu = c.iterator();
        while (itStu.hasNext()) {
            Student s = itStu.next();
            if (s.getName() == "lisi") {
//                c.remove(s1);       会报错
                itStu.remove();       //删除遍历得到的元素
            }
            System.out.println(s);
        }
        System.out.println(c);

方法:

        hasNext()        是否还有下一个元素:通过cursor字段,判断是否到达集合边界

        next()               先让游标后移一位,再返回索引元素

        remove()          删除元素

        public E next() {
            checkForComodification();
            int i = cursor;
            ...
            Object[] elementData = ArrayList.this.elementData;
            ...
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }

        //不能直接调用,remove前需要调用next(),因为本方法中    lastRet字段
        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                ArrayList.this.remove(lastRet);
                cursor = lastRet;
                lastRet = -1;        //更新  lastRet
                expectedModCount = modCount;    //执行完 remove后,更新 expectedModCount 
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

ListIterator迭代器

描述:        弥补了Iterator迭代过程中,不能增加元素

功能:

        1,双向遍历

        2,遍历过程中,可以使用迭代器方法,增删改集合元素

注意:

        1,删除元素前,必须调用next(),否则会报错

           因为remove()中,更新 lastRet=-1,而要调用remove(),会先校验lastRet<0,抛异常

        2,下面代码中,如果没有调用next(),只是单纯的add(), 会导致死循环,直到内存溢出,引发错误

                解决方案:       

                     add()  和 next()  一起使用

范例:

        ArrayList<Student> c = new ArrayList<Student>();
        Student s1 = new Student("zhang", 12);
        Student s2 = new Student("lsii", 23);
        Student s3 = new Student("wangwu", 24);
        Student s4 = new Student("zhoaliu", 24);

        c.add(s1);
        c.add(s2);
        c.add(s3);
        c.add(s4);

        ListIterator<Student> listIterator = c.listIterator();
        while(listIterator.hasNext()){
            listIterator.add(s3);
//            listIterator.remove();    //直接删除会报错,需要先获取,再删除,
                                        //因为remove()后,更新  lastRet=-1
            Student next = listIterator.next();
            System.out.println(next);
        }

方法:

        hasNext()        是否还有下一个元素:通过cursor字段,判断是否到达集合边界

                                继承自Iterator

        next()               返回下一个元素,继承自Iterator

        hasPrevious     是否还有上一个元素

        previous()        返回上一个元素

        add ()            增加元素

        remove()          删除元素,继承自Iterator

    private class ListItr extends Itr implements ListIterator<E> {
        ListItr(int index) {
            super();
            cursor = index;
        }
 
       public boolean hasPrevious() {
            return cursor != 0;
        }

        public E previous() {
            checkForComodification();
            int i = cursor - 1;
            ...
            Object[] elementData = ArrayList.this.elementData;
            ...
            cursor = i;
            return (E) elementData[lastRet = i];
        }

        public void add(E e) {
            checkForComodification();

            try {
                int i = cursor;
                ArrayList.this.add(i, e);
                cursor = i + 1;
                lastRet = -1;        //更新  lastRet
                expectedModCount = modCount;    //执行完add后,更新  expectedModCount 
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

方式2:增强for循环

        Collection<String> strC = new ArrayList<String>();
        strC.add("fa");
        strC.add("");
        strC.add("");
        strC.add("");
        strC.add("ffdasfa");
        for (String s : strC) {
            System.out.println(s);
        }

底层实现:

        增强for循环,运行的时候,编译器为其生成1个Iterator迭代器,调用iterator的hasNext(),next()方法进行遍历

缺点: 和iterator迭代器一样,只读

        1,只能单向遍历

        2,遍历时,不能 向集合中 增加和修改元素,不能删除元素

方式3:普通for循环

优势:可以在 遍历集合的同时,对集合元素进行增删改

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值