Java的线程访问越界会导致Exception in thread "main" java.util.NoSuchElementException
异常的出现。如下是一个因为多次使用迭代器的next()导致的线程越界问题。
源代码
import java.util.HashMap;
import java.util.Iterator;
public class MapImp {
public static void main(String[] args) {
HashMap<Integer, Object> hashMap = new HashMap<>();
hashMap.put(1, "张三");
hashMap.put(2, "李四");
hashMap.put(3, "王五");
hashMap.put(4, "赵六");
for (int i = 5; i < 100; i++) {
hashMap.put(i, "哈密"+i);
}
System.out.println(hashMap);
Iterator<Integer> iterator = hashMap.keySet().iterator();
while (iterator.hasNext()) {
//想要获得的结果是key以及对应的value值,如66:哈密66
System.out.println(iterator.next() + " : " + hashMap.get(iterator.next()));
}
}
}
报错
95 : 哈密96
97 : 哈密98
Exception in thread "main" java.util.NoSuchElementException
at java.base/java.util.HashMap$HashIterator.nextNode(HashMap.java:1607)
at java.base/java.util.HashMap$KeyIterator.next(HashMap.java:1628)
at MapImp.main(MapImp.java:17)
进程已结束,退出代码为 1
分析原因
next() - 返回迭代器的下一个元素,并将迭代器的指针移到下一个位置。
分析源码
在上面的迭代器操作中看出,使用第一次next()
获得一个key
,比如key=95
,此时指针移到下一个位置,调用hashMap.get(iterator.next())
获得是下一个key=96
的值:哈密96,而不是想要的:哈密95。所以上面一次迭代一次移动的指针是两次。当访问的最后一个key的时候,hasNext 判断可以,进入,但是指针移动两次,之后必然会导致指针访问异常。
解决办法
只使用一次next()
操作。提取key获得一个变量,然后进行后续操作。
while (iterator.hasNext()) {
Integer key = iterator.next();
System.out.println(key);
System.out.println(hashMap.get(key));
}