我正在尝试通过使用迭代器在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 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)
我正在使用的代码是这样:
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;
}
答案 0 :(得分:3)
您的代码有很多问题。例如,如果输入是[1]和[1,2],它将抛出NoSuchElementException
:
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
此外,如果base
的元素多于target
,则您的代码可能会陷入无限循环(查找时,第一个循环始终为true
,第二个循环始终为false
base
的最后一个元素)。
在这里,IllegalStateException
可能是因为您要在空白的remove
上调用ArrayList
,但是我无法重现此问题。
如果无法通过此提示修复代码,我将添加解决方案。
提示:将两个循环合并为一个,同时在一个hasNext
循环中同时评估2个条件while
。
答案 1 :(得分:0)
这完成了工作。
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;
}
答案 2 :(得分:0)
无需使用迭代器即可获得两个List<Integer>
的公共元素。可能会引发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;
}
这也可以使用经典循环来完成。