Java 比较列表时的迭代非法状态验证
我试图通过使用迭代器在arraylist中获得类似的项。 我一直遇到这个错误:Java 比较列表时的迭代非法状态验证,java,arraylist,iterator,Java,Arraylist,Iterator,我试图通过使用迭代器在arraylist中获得类似的项。 我一直遇到这个错误: Exception in thread "main" java.lang.IllegalStateException at java.util.ArrayList$Itr.remove(ArrayList.java:872) at com.fryslan.updater.wrappers.MethodDataItem.getIntListSimilarities(MethodDataItem.java:97) at
Exception in thread "main" java.lang.IllegalStateException
at java.util.ArrayList$Itr.remove(ArrayList.java:872)
at com.fryslan.updater.wrappers.MethodDataItem.getIntListSimilarities(MethodDataItem.java:97)
at com.fryslan.updater.wrappers.MethodDataItem.matchAbstractNodes(MethodDataItem.java:67)
at com.fryslan.updater.wrappers.MethodDataItem.equals(MethodDataItem.java:182)
at com.fryslan.updater.Updater.<init>(Updater.java:57)
at com.fryslan.updater.Updater.main(Updater.java:99)
线程“main”java.lang.IllegalStateException中的异常
位于java.util.ArrayList$Itr.remove(ArrayList.java:872)
位于com.fryslan.updater.wrappers.MethodDataItem.GetIntListComplications(MethodDataItem.java:97)
位于com.fryslan.updater.wrappers.MethodDataItem.matchAbstractNodes(MethodDataItem.java:67)
位于com.fryslan.updater.wrappers.MethodDataItem.equals(MethodDataItem.java:182)
更新程序(updater.java:57)
位于com.fryslan.updater.updater.main(updater.java:99)
我使用的代码是:
private ArrayList<Integer> getIntListSimilarities(ArrayList<Integer> base, ArrayList<Integer> target) {
ArrayList<Integer> matching = new ArrayList<>();
Iterator baseIterator = base.listIterator();
Iterator targetIterator = target.listIterator();
while (baseIterator.hasNext()) {
while (targetIterator.hasNext()) {
int bv = (int) baseIterator.next();
int tv = (int) targetIterator.next();
if (bv == tv) {
matching.add(bv);
baseIterator.remove();
targetIterator.remove();
baseIterator = base.listIterator();
targetIterator = target.listIterator();
}
}
}
return matching;
}
private ArrayList GetIntListComplications(ArrayList基,ArrayList目标){
ArrayList匹配=新的ArrayList();
迭代器baseIterator=base.listIterator();
迭代器targetIterator=target.listIterator();
while(baseIterator.hasNext()){
while(targetIterator.hasNext()){
int bv=(int)baseIterator.next();
int tv=(int)targetIterator.next();
如果(bv==tv){
匹配。添加(bv);
baseIterator.remove();
targetIterator.remove();
baseIterator=base.listIterator();
targetIterator=target.listIterator();
}
}
}
返回匹配;
}
您的代码有很多问题。例如,如果输入为[1]和[1,2],它将抛出一个NoTouchElementException
:
baseIterator.remove(); // remove the element from ArrayList<Integer> base
...
baseIterator = base.listIterator(); // new Iterator from the base that had its element removed
...
while (targetIterator.hasNext()); // looking at the 2nd Integer in [1,2]
...
int bv = (int) baseIterator.next(); // NoSuchElementException
baseIterator.remove();//从ArrayList基中删除元素
...
baseIterator=base.listIterator();//已删除元素的基中的新迭代器
...
while(targetIterator.hasNext());//查看[1,2]中的第二个整数
...
int bv=(int)baseIterator.next();//非接触性异常
此外,如果base
的元素多于target
,那么代码可能会进入无限循环(当查看base
的最后一个元素时,第一个循环总是true
,第二个循环总是false
)
在这里,IllegalStateException
可能是因为您在空的ArrayList
上调用了remove
,但是我无法重现该问题
如果您无法使用此提示修复代码,我将添加一个解决方案 提示:将两个循环合并为一个,在一个
循环中同时计算两个条件hasNext
。这样做了
private ArrayList<Integer> getIntListSimilarities(ArrayList<Integer> base, ArrayList<Integer> target) {
ArrayList<Integer> matching = new ArrayList<>();
Iterator baseIterator = base.listIterator();
Iterator targetIterator = target.listIterator();
while (baseIterator.hasNext() && targetIterator.hasNext()) {
int bv = (int) baseIterator.next();
int tv = (int) targetIterator.next();
if (bv == tv) {
matching.add(bv);
baseIterator.remove();
targetIterator.remove();
}
}
return matching;
}
private ArrayList GetIntListComplications(ArrayList基,ArrayList目标){
ArrayList匹配=新的ArrayList();
迭代器baseIterator=base.listIterator();
迭代器targetIterator=target.listIterator();
while(baseIterator.hasNext()&&targetIterator.hasNext()){
int bv=(int)baseIterator.next();
int tv=(int)targetIterator.next();
如果(bv==tv){
匹配。添加(bv);
baseIterator.remove();
targetIterator.remove();
}
}
返回匹配;
}
您可以获得两个列表的公共元素,而无需使用迭代器。可能会抛出IllegalStateException
,因为在使用行进行迭代时,正在重置迭代器
baseIterator = base.listIterator();
targetIterator = target.listIterator();
我觉得这样做毫无意义
下面是一个如何查找两个列表的公共元素的示例,它需要Java 8:
public static List<Integer> getCommonElementsOf(List<Integer> firstList, List<Integer> secondList) {
List<Integer> commonElements = new ArrayList<Integer>();
firstList.forEach(element -> {
if (secondList.contains(element)) {
commonElements.add(element);
}
});
return commonElements;
}
publicstaticlist getCommonElementsOf(List firstList,List secondList){
List commonElements=new ArrayList();
firstList.forEach(元素->{
if(secondList.contains(元素)){
公共元素。添加(元素);
}
});
返回公共元素;
}
这也可以使用经典循环来完成。当然就是这样!我不太熟悉迭代,所以我像处理循环一样处理它。合并hasNexts修复了它。谢谢你的帮助。