赞
踩
1、遍历有值的Set集合,做了remove操作
Set<String> groupNames = new TreeSet<>();
……
List<GroupResDTO> exist = listGroupByNames(dto).getData();
// 去除已存在分组
if (CheckUtil.isNotNullAndNotEmpty(exist)) {
for (String tmp : groupNames) {
for (GroupResDTO eDto : exist) {
if (tmp.equals(eDto.getGroupName())) {
groupNames.remove(tmp);
}
}
}
}
由于遍历的是groupNames对象,而又在符合条件的时候将groupNames 中的内容移除导致下一次循环的时候抛出空指针异常。解决方法是遍历对象为groupNames 的复制对象:
Set<String> newSet = new HashSet<>(groupNames);
if (CheckUtil.isNotNullAndNotEmpty(exist)) {
for (String tmp : newSet ) {
for (GroupResDTO eDto : exist) {
if (tmp.equals(eDto.getGroupName())) {
groupNames.remove(tmp);
}
}
}
}
新的解决方法(感谢评论中大佬的建议):
使用迭代器遍历并更改了遍历顺序(先遍历比对的对象A,再遍历需要做remove操作的对象B)。
如果采用的先遍历B再遍历A的顺序会导致遍历不完全。原因当迭代器对象it进行了remove操作之后,it.next()立马就变了,而此时还在A的遍历循环里面,出现A的第一次遍历还没完成,it.next()值已经变了的情况,继而会用新的it.next()比对A的下一个对象,整个双重循环就被破坏了。
因而改变了遍历顺序,这样可以保证双重循环稳定性。代码如下:
if (CheckUtil.isNotNullAndNotEmpty(exist)) {
for (GroupResDTO eDto : exist) {
// 获取容器指针,此时指针指向第一个元素的前面(内置的一个空元素)
Iterator<String> it = groupNames.iterator();
// hasNext仅判断,不移动指针
while (it.hasNext()) {
// next方法移动指针指向下一个,并返回指向的当前元素
if (eDto.getGroupName().equals(it.next())) {
// remove 合法移除指针指向的当前元素
it.remove();
}
}
}
}
以上代码简写如下:
if (CheckUtil.isNotNullAndNotEmpty(exist)) {
for (GroupResDTO eDto : exist) {
groupNames.removeIf(s -> eDto.getGroupName().equals(s));
}
}
2、遍历空集合对象
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。