谷歌网站推广优化,百度网站怎么做的赚钱吗,搭建漏洞网站,外加工网目录
异常代码片段
详细说明
解决方案
使用迭代器进行遍历
使用临时集合存储结果 异常代码片段
if (ObjectUtil.isNotEmpty(candidateUsers)) {candidateUsers candidateUsers.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());for (String …目录
异常代码片段
详细说明
解决方案
使用迭代器进行遍历
使用临时集合存储结果 异常代码片段
if (ObjectUtil.isNotEmpty(candidateUsers)) {candidateUsers candidateUsers.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());for (String candidateUser : candidateUsers) {if (ObjectUtil.isNotEmpty(candidateUser) candidateUser.contains(${)) {try {String expressionValue expressionService.getStrValue(extendHisprocinst.getProcessInstanceId(), candidateUser);candidateUsers.add(expressionValue);} catch (Exception e) {log.error(解析人员报错原因{}, ExceptionUtil.stacktraceToString(e));}}}
}
这段代码中出现ConcurrentModificationException异常的原因是在遍历candidateUsers集合的同时对其进行了修改。
具体来说是在遍历过程中通过candidateUsers.add(expressionValue);向集合中添加元素这会导致ConcurrentModificationException异常。
详细说明 详细解释 1.集合的遍历机制 当你使用for-each循环遍历集合时实际上是在使用迭代器Iterator来遍历集合中的元素。 迭代器在遍历集合时会维护一个内部计数器以跟踪当前遍历的位置。 每次调用next()方法时迭代器会移动到下一个位置并返回当前位置的元素。 2.并发修改检测 Java集合框架中的许多集合类如ArrayList在遍历期间会检查集合是否被修改过。 这种检查是通过一个称为modCount的字段来实现的每当集合被修改时例如添加或删除元素modCount值就会增加。 迭代器有一个expectedModCount字段它在迭代器创建时被初始化为集合的modCount值。 在每次调用next()方法时迭代器会检查expectedModCount是否等于集合的当前modCount值。 如果expectedModCount与当前modCount不匹配说明集合在遍历过程中被修改过这时迭代器会抛出ConcurrentModificationException异常。 代码分析 在这段代码中首先使用了流操作过滤并去重candidateUsers集合然后遍历这个集合。在遍历过程中如果满足某个条件即candidateUser包含${会尝试从expressionService获取表达式的值并将其添加回candidateUsers集合中。这种做法违反了遍历过程中的并发修改规则因此抛出了ConcurrentModificationException异常。 解决方案
为了避免这个问题可以采用以下几种方法之一。
使用迭代器进行遍历
使用迭代器遍历集合并在外部循环中处理元素避免直接修改正在遍历的集合。
这种方法避免了直接修改正在遍历的集合而是使用迭代器来安全地访问集合中的元素。
if (ObjectUtil.isNotEmpty(candidateUsers)) {candidateUsers candidateUsers.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());IteratorString iterator candidateUsers.iterator();while (iterator.hasNext()) {String candidateUser iterator.next();if (ObjectUtil.isNotEmpty(candidateUser) candidateUser.contains(${)) {try {String expressionValue expressionService.getStrValue(extendHisprocinst.getProcessInstanceId(), candidateUser);candidateUsers.add(expressionValue);} catch (Exception e) {log.error(解析人员报错原因{}, ExceptionUtil.stacktraceToString(e));}}}
} 使用临时集合存储结果
创建一个新的集合来存储处理后的结果而不是直接修改原始集合。从而避免了ConcurrentModificationException异常。 选择其中一种方法即可解决问题。如果需要保留原始集合的内容建议使用第二种方法使用临时集合存储结果。 if (ObjectUtil.isNotEmpty(candidateUsers)) {ListString tempCandidateUsers new ArrayList();candidateUsers candidateUsers.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());for (String candidateUser : candidateUsers) {if (ObjectUtil.isNotEmpty(candidateUser) candidateUser.contains(${)) {try {String expressionValue expressionService.getStrValue(extendHisprocinst.getProcessInstanceId(), candidateUser);tempCandidateUsers.add(expressionValue);} catch (Exception e) {log.error(解析人员报错原因{}, ExceptionUtil.stacktraceToString(e));}} else {tempCandidateUsers.add(candidateUser);}}candidateUsers tempCandidateUsers;
}