精华内容
下载资源
问答
  • } } } } 运行,然后看看报错: C:\Users\hzy\Desktop>javac Test.java C:\Users\hzy\Desktop>java Test 0 1 2 3 4 Exception in thread "main" java.util.ConcurrentModificationException at java.base/java.util....

    前言

    二十多天的实训结束了,虽然环境emmmm有点坑,好多人都感冒了,我也没能逃过一劫。 不过总体来说还行,第一次尝试跟学校里不一样的,7个人一起做项目。 不过也因此对于github的使用不再局限于之前的将其作为云服务备份来使用了,更多的还是大家上传代码,合并冲突之类的,还有也学会了git stash的一些个基础用法,嘻嘻。

    这个月还没写点东西记录一下。 这里就记录一下之前遇到过的一个,算是比较突然,意想不到的错吧。

    以下有的是网上查到的资料,再加上了一点点自己的理解,感觉还是有些地方不太懂,如果有什么错误还请批评指正。

    问题

    目标:想要在循环遍历的过程中删除集合中的元素,但是运行代码的时候遇到了这么一个错: java.util.ConcurrentModificationException: null

    这里写图片描述

    这里写图片描述

    原因

    简单地说下原因,在我那个项目的代码中,遍历的方式是用Itr去遍历的,这个Itr是ArrayList实现的一个遍历接口。

    但是我在删除的时候是通过ArrayList的remove方法去操作的,不是Itr内部的那个删除方法去操作的。

    所以,在用ArrayList的remove方法进行删除操作以后,Itr里面的expectedModCount会与ArrayList的modCount进行比较,二者不相等,所以会抛错。

    另,貌似直接用Itr的remove方法也可以解决问题,不需要像我最后的处理方式那样复杂。并且,ArrayList 是一个查询为主的数据结构,本身就不太适合修改频繁以及并发修改的场景。

    分析

    这里我写了一个方便问题复现的代码:

    import java.util.ArrayList;
    
    class Test{
        public static void main(String[] args){
            ArrayList<Integer> arr = new ArrayList<Integer>();
            for(int i=0; i<10; i++){
                arr.add(i);
            }
    
            for(Integer i: arr){
                if(i == 5){
                    arr.remove(i);
                }
                else{
                    System.out.println(i);
                }
            }
        }
    }
    

    运行,然后看看报错:

    C:\Users\hzy\Desktop>javac Test.java
    
    C:\Users\hzy\Desktop>java Test
    0
    1
    2
    3
    4
    Exception in thread "main" java.util.ConcurrentModificationException
            at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1009)
            at java.base/java.util.ArrayList$Itr.next(ArrayList.java:963)
            at test.main(test.java:10)
    

    ok,报错的是ArrayList.java里的Itr.next()和Itr.checkForComodification()。

    这里的Itr是在ArrayList的内部类,实现了Iterator接口,用于遍历。

    public class ArrayList<E> extends AbstractList<E>
            implements List<E>, RandomAccess, Cloneable, java.io.Serializable
    {
    	... ...
    	        
    	/**
         * An optimized version of AbstractList.Itr
         */
        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;
    
            // prevent creating a synthetic constructor
            Itr() {}
    
            public boolean hasNext() {
                return cursor != size;
            }
    
            @SuppressWarnings("unchecked")
            public E next() {
                checkForComodification();
                int i = cursor;
                if (i >= size)
                    throw new NoSuchElementException();
                Object[] elementData = ArrayList.this.elementData;
                if (i >= elementData.length)
                    throw new ConcurrentModificationException();
                cursor = i + 1;
                return (E) elementData[lastRet = i];
            }
    
            public void remove() {
                if (lastRet < 0)
                    throw new IllegalStateException();
                checkForComodification();
    
                try {
                    ArrayList.this.remove(lastRet);
                    cursor = lastRet;
                    lastRet = -1;
                    expectedModCount = modCount;
                } catch (IndexOutOfBoundsException ex) {
                    throw new ConcurrentModificationException();
                }
            }
    
            @Override
            public void forEachRemaining(Consumer<? super E> action) {
                Objects.requireNonNull(action);
                final int size = ArrayList.this.size;
                int i = cursor;
                if (i < size) {
                    final Object[] es = elementData;
                    if (i >= es.length)
                        throw new ConcurrentModificationException();
                    for (; i < size && modCount == expectedModCount; i++)
                        action.accept(elementAt(es, i));
                    // update once at end to reduce heap write traffic
                    cursor = i;
                    lastRet = i - 1;
                    checkForComodification();
                }
            }
    
            final void checkForComodification() {
                if (modCount != expectedModCount)
                    throw new ConcurrentModificationException();
            }
        }
    	... ...
    

    报错就是在Itr.next()中调用checkForComodification()以后产生的,在checkForComodification()函数中,判断了modCount和expectedModCount是否相等。如果不相等,就会抛出我们遇到的这个异常。

    显然,我们的报错就是因为这两个变量不相等导致的。

    		... ...
    		@SuppressWarnings("unchecked")
            public E next() {
                checkForComodification();
                int i = cursor;
                if (i >= size)
                    throw new NoSuchElementException();
                Object[] elementData = ArrayList.this.elementData;
                if (i >= elementData.length)
                    throw new ConcurrentModificationException();
                cursor = i + 1;
                return (E) elementData[lastRet = i];
            }
    		... ...
            final void checkForComodification() {
                if (modCount != expectedModCount)
                    throw new ConcurrentModificationException();
            }
    

    ok,那这两个变量是什么含义呢?

    • modCount是modification count的缩写,也就是当前的ArrayList被修改的次数,这个变量是ArrayList继承自AbstractList的。

      可以在IDE中,按住Ctrl键,然后鼠标点一下变量modCount,就可以跳转到定义它的地方了~

    • expectedModCount是expected modification count的缩写,也就是期望被修改的次数,这个变量是在内部类Itr中定义的,初始时赋值为modCount。

    ok,那为什么我们的写法会导致这两个变量不一致呢?

    这里要注意的是,我遍历的时候调用的是Itr.next(),但是我在循环中删除元素时,用的是ArrayList.this.remove():

    public class ArrayList<E> extends AbstractList<E>
            implements List<E>, RandomAccess, Cloneable, java.io.Serializable
    {
        ... ...
    	public boolean remove(Object o) {
            final Object[] es = elementData;
            final int size = this.size;
            int i = 0;
            found: {
                if (o == null) {
                    for (; i < size; i++)
                        if (es[i] == null)
                            break found;
                } else {
                    for (; i < size; i++)
                        if (o.equals(es[i]))
                            break found;
                }
                return false;
            }
            fastRemove(es, i);
            return true;
        }
        
        private void fastRemove(Object[] es, int i) {
            modCount++;
            final int newSize;
            if ((newSize = size - 1) > i)
                System.arraycopy(es, i + 1, es, i, newSize - i);
            es[size = newSize] = null;
        }
        ... ...
    

    remove()函数会调用fastRemove()函数,使得modCount的值自增1.

    然而,for循环下一次调用Itr.next(),Itr.next()调用Itr.checkForComodification()时,会发现,modCount和expectedModCount两个值不相等!因为在这个删除操作的过程中没有对expectedModCount重新赋值,所以就抛出异常了。

    – 于2021.4.11修改(解决方案在文章末尾…


    下面是以前的文章的内容了… 写的烂七八糟的,舍不得删了hh

    最后在网上看了一下,才发现是循环的时候,进行了删除的操作,所以才会报错,原因在于: 迭代器的expectedModCount和modCount的值不一致;
    我代码中的这个recruitList是个ArrayList,而且循环中是一个迭代器来进行迭代的(参考java forEach实现原理). 因此不妨去看一下它的iterator实现方法:
    这里写图片描述
    根据注释可以看到, 返回的是一个指向Itr类型对象的正确顺序的引用(@return an iterator over the elements in this list in proper sequence);

    然后往下可以看到Itr这个内部类的实现:
    由注释可以看到:

    1. cursor是下一个返回的元素的下标;
    2. lastRet 是最后一个返回的元素的索引下标;
    3. expectedModCount:是对ArrayList修改次数的预期的数值,被初始化为modCount; 注意,这里expectedModCount是内部类 Itr 中的变量,而modCountArrayList继承自AbstractList的一个成员变量
    4. 在这个内部类的末尾我看到了, if (modCount != expectedModCount) throw new ConcurrentModificationException(); 看来这就是问题所在; 只是这个modCount是什么呢?
    /**
     * An optimized version of AbstractList.Itr
     */
    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;
    
        Itr() {}
    
        public boolean hasNext() {
            return cursor != size;
        }
    
        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }
    
        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();
    
            try {
                ArrayList.this.remove(lastRet);
                cursor = lastRet;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }
    
        @Override
        @SuppressWarnings("unchecked")
        public void forEachRemaining(Consumer<? super E> consumer) {
            Objects.requireNonNull(consumer);
            final int size = ArrayList.this.size;
            int i = cursor;
            if (i >= size) {
                return;
            }
            final Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length) {
                throw new ConcurrentModificationException();
            }
            while (i != size && modCount == expectedModCount) {
                consumer.accept((E) elementData[i++]);
            }
            // update once at end of iteration to reduce heap write traffic
            cursor = i;
            lastRet = i - 1;
            checkForComodification();
        }
    
        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }
    

    ArrayList.javactrl 点一下 modCount找一下,发现modCountArrayList继承自AbstractList的一个成员变量, 表示对List的修改次数,由注释可知,只要有改变,modCount就会加上1;
    那我代码里的remove()方法又为什么会引起异常呢?
    ArrayList中的内部类Itr中的next()方法中可以看到:
    这里写图片描述
    一开始会调用checkForComodification();方法进行检查,初始时,cursor为0,lastRet为-1,在调用一次之后,cursor的值为1,lastRet的值为0,modCount为0,expectedModCount也为0。
    再来看代码中的remove()方法做了什么:
    这里写图片描述
    在这里调用了ArrayList.this.remove(lastRet);

    1. 对于iterator,其expectedModCount为0,cursor的值为1,lastRet的值为0;
    2. 对于list,其modCount为1,size为0;

    那么在下一次调用时, 执行checkForComodification()方法,就会遇到ConcurrentModificationException异常了,问题在于:调用list.remove()方法导致modCountexpectedModCount的值不一致
    这里写图片描述



    解决

    我解决的方法是改成索引遍历,但是需要在删除之后保证索引的正常:
    这里写图片描述
    参考:Java ConcurrentModificationException 异常分析与解决方案

    展开全文
  • import com.supcon.mare.common.util.Pagination; import org.dozer.DozerBeanMapperBuilder; import org.dozer.Mapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework....
    package com.supcon.oms.utils;
    
    import com.supcon.mare.common.util.Pagination;
    import org.dozer.DozerBeanMapperBuilder;
    import org.dozer.Mapper;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.data.domain.Page;
    import org.springframework.stereotype.Component;
    import org.springframework.util.CollectionUtils;
    import java.util.*;
    
    /**
     * @author: zhaoxu
     * @date: 2020/9/10 19:10
     */
    @Component
    public class BaseConverter {
        private static final Logger log = LoggerFactory.getLogger(com.supcon.mare.common.util.BaseConverter.class);
        Mapper beanMapper = DozerBeanMapperBuilder.buildDefault();
    
        public BaseConverter() {
        }
    
        public <S, D> D convertSingleObject(S source, Class<D> clazz) {
            if (source == null) {
                return null;
            } else {
                D dest = null;
    
                try {
                    dest = beanMapper.map(source, clazz);
                } catch (Exception var5) {
                    log.error("初始化{}对象失败。", clazz, var5);
                }
    
                return dest;
            }
        }
    
        public <S, D> List<D> convertMultiObjectToList(List<S> sourceList, Class<D> destClass) {
            if (CollectionUtils.isEmpty(sourceList)) {
                return null;
            } else {
                List<D> toList = new ArrayList();
                Iterator var4 = sourceList.iterator();
    
                while(var4.hasNext()) {
                    Object src = var4.next();
                    toList.add(this.convertSingleObject(src, destClass));
                }
    
                return toList;
            }
        }
    
        public <S, D> Map<String, Object> convertMultiObjectToMap(Page<S> srcPages, Class<D> destClass) {
            Map<String, Object> destMap = new HashMap(100);
            Pagination pagination = new Pagination();
            List<D> destList = new ArrayList();
            if (srcPages != null && srcPages.getContent() != null) {
                Iterator var6 = srcPages.getContent().iterator();
    
                while(var6.hasNext()) {
                    Object src = var6.next();
                    destList.add(this.convertSingleObject(src, destClass));
                }
            }
    
            pagination.setTotalPages(srcPages.getTotalPages());
            pagination.setTotal(srcPages.getTotalElements());
            pagination.setCurrent(srcPages.getNumber() + 1);
            pagination.setPageSize(srcPages.getSize());
            destMap.put("total",srcPages.getTotalElements());
            destMap.put("data", destList);
            destMap.put("pageSize", srcPages.getSize());
            destMap.put("current", srcPages.getNumber() + 1);
            return destMap;
        }
    }
    
    展开全文
  • 背景:使用SSM框架; 操作:访问项目中的一个页面后,使用浏览器的回退键再次访问该页面; 错误: Description The server encountered an unexpected condition that prevented...org.springframework.web.util.N...
    背景:使用SSM框架;
    操作:访问项目中的一个页面后,使用浏览器的回退键再次访问该页面;
    错误:
    Description The server encountered an unexpected condition that prevented it from fulfilling the request.
    
    Exception
    
    org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException
    	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1013)
    	org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897)
    	javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
    	org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
    	javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    	org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
    	org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)

    错误出现的原因:处理该请求的方法所需要的部分参数在请求时没有值,导致空指针错误;

    解决方法一:在第一次访问该页的请求,或者说访问出错的页请求链接上加上处理该请求的方法所需的参数

    解决方法二:配置两个处理请求的方法,一个无参(用于第一次访问),一个有参,用于处理有参数的请求。

    展开全文
  • NonfairSync(int permits) { super(permits); }
  • Md5Util和Base64Util加密

    千次阅读 2016-12-06 13:27:37
    Md5Util和Base64Util加密

    Md5Util

    public class Md5Util {
        public static String encode(String str){
            try {
                MessageDigest md5 = MessageDigest.getInstance("md5");
                byte []afterEncode = md5.digest(str.getBytes());
    
                //Base64编码  它的作用是用于将非ascii码转成ascii码
                BASE64Encoder b64 = new BASE64Encoder();
                return b64.encode(afterEncode);
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        }
    
        public static void main(String[] args) {
            for (int i = 0; i <20; i++) {
                String result  = Md5Util.encode("aaa"+i);
                System.out.println(result);
            }
        }
    }

    Base64Util

    public class Base64Util {
    
        // 编码
        public static String encode(String str) {
            BASE64Encoder b64 = new BASE64Encoder();
            return b64.encode(str.getBytes());
        }
    
        // 还原
        public static String decode(String str) {
            try {
                BASE64Decoder b64decoder = new BASE64Decoder();
                byte[] after = b64decoder.decodeBuffer(str);
                return new String(after);
            } catch (IOException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        }
    }
    展开全文
  • jacksonUtil

    千次阅读 2013-12-03 20:27:49
    import java.io.IOException;...import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.fasterxml.jackson.core.JsonProcessingException; import com.fa
  • SpringUtil

    千次阅读 2014-03-11 00:43:31
    public class SpringUtil { private static Log logger = LogFactory.getLog(SpringUtil.class); /** Spring框架应用上下文对象 */ private static ApplicationContext factory = getApplicationContext(); ...
  • HttpClientUtil

    千次阅读 2012-08-12 22:49:30
    package sdcncsi.ict.site.web.xzsp;...import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.http.HttpEntity; import org.apache.http.Ht
  • 转载请注明出处:http://blog.csdn.net/l1028386804/article/details/51538611 注:升级glib库解决问题请参加链接:... 配置完hadoop启动的时候出现如下警告信息: WARN util.NativeCodeLoad...
  • Cause: org.jetbrains.plugins.gradle.tooling.util.ModuleComponentIdentifierImpl.getModuleIdentifier() 究其原因,是gradle版本导致的。从它的报错也能看出,跟我们自己写的代码无关。 怎么改呢? 凡应用gradle...
  • ImportError: No module named python_util.util

    千次阅读 2016-09-18 19:22:00
    从师兄那里拷贝了一个python文件,运行报错ImportError: No module named python_util.util,python小白上网搜,并没有搜到有价值的答案。。。经过摸索,最后解决。 其实这就是缺少python_util.util,到这个网址...
  • util.promisify

    千次阅读 2018-04-16 19:34:03
    其中比较值得注意的,便有 util.promisify() 这个方法。 util.promisify() 虽然 Promise 已经普及,但是 Node.js 里仍然有大量的依赖回调的异步函数,如果我们每个函数都封装一次,也是齁麻烦齁麻烦的,比齁还麻烦...
  • gulp开发团队一直计划弃用gulp-util,因为它只是一堆模块,大概6752个modules,其中许多都使用过了较低版本的Vinyl, 低版本的Vinyl是不兼容的,但仍被许多插件使用,然而Vinyl的v2版不会附带gulp-util,所以开发团队在...
  • 最近使用到了字符串的非空判断,...StringUtil.isEmpty(null) == true StringUtil.isEmpty("") == true StringUtil.isEmpty(" ") == false StringUtil.isEmpty("bbbb") == ...
  • import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.TreeMap; /*  * 统计abacbacdadbc中的每个字母出现的次数,输出格式是:a(4)b(3)c(3)d(2)  *   * 选中TreeMap...
  • @[TOC](解决警告:Unchecked assignment: ‘java.util.HashSet’ to ‘java.util.Set<java.lang.String>’. Unchecked call to ‘HashSet(Collection<? extends E>)’ as a member of raw type ‘java....
  • 一例JSON数组转化错误...org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of `java.util.ArrayList` out of VALUE_STRING token; nested ex...
  • jacksonUtil工具类

    千次阅读 2020-05-06 14:36:50
    import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JavaType; import ... import java.util.List; import java.util...
  • JwtUtil工具

    千次阅读 2018-06-08 20:37:34
    public class JwtUtil { //需要key.map,颜值三个组成部分 //3、 签名部分 //根据用户信息+盐值+密钥生成的签名。 public static String encode(String key, Map&lt;String, Object&gt; param, String ...
  • "import java.util.Scanner"与"import java.util.*"的区别:

    千次阅读 多人点赞 2019-04-01 16:40:38
    "import java.util.Scanner"与"import java.util.*"的区别: 1、“importjava.util.*;”表示的是把util这个包下的全部类导入到程序中;而“importjava.util.Scanner;”表示的是只把util包下的Scanner类导入到程序...
  • 10node.js工具类util.inherits和util.inspect

    千次阅读 2016-10-11 19:58:20
    10月11号:今天你在哪一步? 1:什么是util util是node.js核心模块,提供常用函数的集合,用于弥补核心js的功能 2:util.inherits util.inherits是一个实现对象间原型...var util = require('util'); function Bas
  • “importjava.util.*;”和“importjava.util.Scanner;”的区别有以下几点:    1、“importjava.util.*;”表示的是把util这个包下的全部类导入到程序中;而“importjava.util.Scanner;”表示的是只把util包下...
  • 在学习spring中注意到其判断配置文件位置的字符串是使用了StringUtil.isEmpty()方法。第一次遇到这种使用方式,感到很新奇。 StringUtil.isEmpty()方法的作用是:判断字符串是否为空即是否为null值或者其长度是否为...
  • package day1501;...import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Scanner; public class Test1 { public static void main(String[] args) {
  • SpringUtil工具类

    千次阅读 2019-08-19 15:58:37
    package com.sykj.util; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; public cla....
  • java.util

    千次阅读 2019-04-11 15:20:06
    Util是utiliy的缩写,是一个多功能、基于工具的包。 Java的实用工具类库java.util包。在这个包中,Java提供了一些实用的方法和数据结构。例如,Java提供日期(Data)类、日历(Calendar)类来产生和获取日期及时间,...
  • Java.util包简单总结

    万次阅读 多人点赞 2017-02-28 00:30:13
    java.util包粗略总结

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 518,801
精华内容 207,520
关键字:

util