学习的过程中遇到的一个问题, 下述代码在尝试remove其他元素的时候会出现异常,而在remove最后一个元素的时候,可以正常运行.
public class Main { public static void main(String[] args) { TreeMap<ModelWorker, String> map = new TreeMap<>(); map.put(new ModelWorker("张三", 18), "北京"); map.put(new ModelWorker("李四", 20), "上海"); map.put(new ModelWorker("王五", 35), "天津"); for (ModelWorker modelWorker : set) { if ("张三".equals(modelWorker.getName())) { map.remove(modelWorkermove(modelWorker)); // 这里尝试remove最后一个对象 } } }}
初步查找后得知,增强for和迭代器遍历的过程中,直接用集合去remove以及其他修改集合的操作很容易出现问题.
之后Debug+翻源码分析了一下异常抛出的原因:
异常是在TreeMap中的一个继承Iterator的抽象类中抛出的
next()方法源码如下throw new ConcurrentModificationException();
这行抛出异常原因显然是因为if条件满足modCount != expectedModCount
虽然不知道为什么jdk这样设计的.这两个变量在TreeMap类的成员变量中定义,没搞懂是干嘛的.先继续往下找找什么操作会导致这两个变量的变化.
final Entry<K,V> nextEntry() { Entry<K,V> e = next; if (e == null) throw new NoSuchElementException(); if (modCount != expectedModCount) throw new ConcurrentModificationException(); next = successor(e); lastReturned = e; return e;}
在remove()方法中发现调用了deleteEntry方法,该方法修改了导致异常抛出的条件的变量.
remove()方法导致变量值修改的核心部分
private void deleteEntry(Entry<K,V> p) { modCount++; size--; // 省略没用的}
目前到这里,仅仅是大致上搞懂了为什么当使用集合的remove方法移除元素的时候会抛异常这点.还有一个问题有待解决,当移除最后一个元素的时候却没有抛出异常.
回头检查自己的代码.增强for在编译后会变成迭代器.反编译后的代码如下.
Iterator<ModelWorker> var3=set.iterator(); while(var3.hasNext()){ ModelWorker1 modelWorker=var3.next(); if("张三".equals(modelWorker.getName())){ map.remove(modelWorker); } }
从这里猜测会不会和代码按顺序执行有关,当remove
最后一个元素后,下一行要执行的是hasNext
,当hasNext
执行完后返回false
后循环会直接结束,而不进入next
方法.并且异常可能只能是next
方法抛出的.
所以顺便查了下hasNext的源码.在此之中果然没有抛出异常的语句.
hasNext()方法的源码
public final boolean hasNext() { return next != null;}
最后得到的结论就是,不要在增强for和迭代器遍历中直接删除集合的元素.如果没抛异常可能就是因为删除的是最后一个元素.
原文转载:http://www.shaoqun.com/a/485973.html
亚马逊 海外购:https://www.ikjzd.com/w/998
海鹰数据:https://www.ikjzd.com/w/2539
ask me:https://www.ikjzd.com/w/2459
学习的过程中遇到的一个问题,下述代码在尝试remove其他元素的时候会出现异常,而在remove最后一个元素的时候,可以正常运行.publicclassMain{publicstaticvoidmain(String[]args){TreeMap<ModelWorker,String>map=newTreeMap<>();map.put(newModelWorker(&qu
cima是什么:https://www.ikjzd.com/w/1372
feedback:https://www.ikjzd.com/w/159
阿里速卖通无忧退保障计划上线:https://www.ikjzd.com/home/18583
深圳北站到福田气车站怎么走最方便?:http://tour.shaoqun.com/a/966.html
出境旅游走丢了怎么办:http://tour.shaoqun.com/a/18376.html
No comments:
Post a Comment