美文网首页
java 集合体系

java 集合体系

作者: 最美下雨天 | 来源:发表于2018-08-29 10:06 被阅读4次

图片来源:https://blog.csdn.net/csp277/article/details/46462605

image.png

Collection继承了Iterable接口

关于集合遍历时增删元素:
这样可以

Iterator<String> iterator=list.iterator();
                while(iterator.hasNext())
                {
                    if(iterator.next().equals("bbb"))
                    {
                        iterator.remove();
                    }

                }

普通for循环也可以

for(int i=0;i<list.size();i++)
                {
                    if(list.get(i).equals("bbb"))
                    {
                        list.remove(i);
                    }
                }

但是增强for循环是不可以的

for(String str:list)
                {
                    if(str.equals("bbb"))
                    {
                        list.remove(str);
                    }
                }

会抛出java.util.ConcurrentModificationException异常
利用迭代器进行迭代时,直接用list删除元素也是不可以的

 Iterator<String> iterator=list.iterator();
                while(iterator.hasNext())
                {
                    String next=iterator.next();
                    if(next.equals("bbb"))
                    {
                        list.remove(next);
                    }

                }

会抛出java.util.ConcurrentModificationException异常


image.png

看异常的日志,是在调用next()方法的时候才抛出的,并非调用list.remove()的时候
为什么抛出了异常,看下ArrayList中的代码:


image.png
image.png

在next()方法的第一句就做了判断
我们调用list.iterator()的时候会初始化Itr

public Iterator<E> iterator() {
        return new Itr();
    }
image.png

初始化时便会对expectedModCount进行赋值,既然next()方法中抛出了异常,说明两个值不等了,那必然是list.remove()方法对modCount进行了修改,看下list.remove()方法


image.png

modCount的值修改了,但是Itr的成员变量expectedModCount的值并没有发生变化,所以这儿抛出了异常。

那么java为什么要这么设计呢,如果不抛出这个异常,继续让程序往下面走,会发生什么情况?

利用迭代器在遍历集合的过程中是利用cursor这个变量控制的

 int cursor;       // index of next element to return

在迭代过程中会利用it.hasNext()来判断是否还有下一个元素

        protected int limit = ArrayList.this.size;

        int cursor;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such
        int expectedModCount = modCount;

        public boolean hasNext() {
            return cursor < limit;
        }

其实这个操作并没有什么影响,这儿是可以正确拿到集合的大小的,但是你会发现在next()遍历中会存在跳过元素的情况


image.png

假设遍历到集合的第二个元素时,删除了第二个元素,但是此时cursor是等于2


image.png

再调用next的时候原先的第三个元素变为了第二个元素,cursor没有做任何操作,值为2,此时就跳过了第二个元素,直接遍历第三个元素了,这就不正常了。

那么调用iterator.remove()方法为什么可以呢?
image.png

因为在这个方法中会同步更新cursor值

相关文章

  • Java基础——集合体系Map详解

    Java基础——集合体系Map详解 上文中我们了解了集合体系中的单列集合:Java基础——集合以及Java集合——...

  • Java基础

    Java集合框架 一、Java集合类简介: Java集合大致分为四种体系:Set:无序、不可重复的集合List:有...

  • Java基础知识点(九)

    一、Java 中的集合框架(上) 1、Java 中的集合框架概述 JAVA集合框架体系结构:Collection与...

  • 社招遇到的问题

    java 集合类继承体系:集合类继承体系 java 中子线程执行完成后再唤醒主线程: thread.join 或 ...

  • java集合详解

    java集合概述 Java 集合可分为 Collection 和 Map 两种体系 Collection接口:单列...

  • Java集合

    目录: Java集合APICollection 体系Set 集合HashSet 的存储机制:HashSet 还有一...

  • 四 集合 ——第八节 Map集合,HashMap详解

    1、Map集合概述 和Collection集合是两套体系,Collection集合是单列集合java.util.M...

  • Java集合框架使用总结

    Java集合框架使用总结 前言: 本文是对Java集合框架做了一个概括性的解说,目的是对Java集合框架体系有个总...

  • Java集合框架源码解读(2)——HashMap

    Java集合框架源码解读(2)——HashMap 在Java Collections Framework的体系中中...

  • Java基础之集合框架

    一、Java集合类简介: Java集合大致可以分为Set、List、Queue和Map四种体系。 其中Set代表无...

网友评论

      本文标题:java 集合体系

      本文链接:https://www.haomeiwen.com/subject/lpsqwftx.html