简体   繁体   English

IndexOutOfBoundsException异常

[英]IndexOutOfBoundsException

Hi this code will return indexoutofboundsException and really I don't know why? 嗨,这段代码将返回indexoutofboundsException ,真的我不知道为什么? I want to remove those objects from pointlist which are as the same as an object in the list . 我想从pointlist删除那些与list的对象相同的对象。

    public void listOfExternalPoints(List<Point> list) {
    System.out.println(list.size());
    System.out.println(pointList.size());
    int n = pointList.size();
    for (int i = pointList.size() - 1; i >= 0; i--) {
        for (int j = 0; j < list.size(); j++) {
            if (pointList.get(i)==(list.get(j))) {
                pointList.remove(i);
                n--;
            }
        }
    }

}

Also the out put of println will be : println的输出也将是:

54
62

Also the exception: 也是例外:

Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 60, Size: 60
    at java.util.ArrayList.RangeCheck(ArrayList.java:547)
    at java.util.ArrayList.get(ArrayList.java:322)
    at ConvexHull.BlindVersion.listOfExternalPoints(BlindVersion.java:83)

thanks. 谢谢。

hey, you removed some elements from the list. 嘿,你从列表中删除了一些元素。 So the list is smaller than it was at the beginning of the loop. 因此列表小于循环开始时的列表。

I suggest you to use: 我建议你用:

pointList.removeAll(list)

Or an iterator. 或者是迭代器。

When you do pointList.remove(i) , you should break from the inner loop. 当你执行pointList.remove(i) ,你应该从内循环中断。 Otherwise, it will try to index pointList.get(i) , which you just removed, again on the next iteration of the loop, which is why are you getting the exception. 否则,它将尝试在循环的下一次迭代中再次索引你刚刚删除的pointList.get(i) ,这就是为什么你得到异常。

When arrayLists remove elements, that element is taken out, and all elements after it gets shifted down. 当arrayLists删除元素时,将取出该元素,并将其后的所有元素向下移动。 So if you remove index 3 and there are only 4 elements, the new arrayList only has size 3 and you try to get index 3, which is out of bounds. 因此,如果删除索引3并且只有4个元素,则新的arrayList只有3大小,并且您尝试获取索引3,这是超出范围的。

EDIT: A better way to do this is: 编辑:更好的方法是:

for(Point p : list) {
    pointList.remove(p);
}

It will have the same efficiency, but more correct, I think. 它会有相同的效率,但我认为更正确。 Remember that == compares references for the same object. 请记住, ==比较同一对象的引用。 Where as the remove method uses .equals to check for equality, which is what I assume you want. remove方法使用.equals检查是否相等,这就是我想要的。

pointList.remove(i); pointList.remove(ⅰ);

This will decrease your pointList size. 这将减少你的pointList大小。 Hope this helps. 希望这可以帮助。

Removing the object from pointList will reduce its size. 从pointList中删除对象将减小其大小。 Therefore, in one iteration of the "for j" block, you may be removing two elements of PointList, shifting all other elements to the left. 因此,在“for j”块的一次迭代中,您可能正在移除PointList的两个元素,将所有其他元素移到左侧。 However, in the next iteration "i" will refer to an out of bounds location (60). 然而,在下一次迭代中,“i”将指代越界位置(60)。

The problem is with the order of loop evaluation. 问题在于循环评估的顺序。 You are only evaluating the length of pointList once, and never checking it again. 您只评估一次pointList的长度,而不再检查它。

If you remove the last item from pointList , and you have not reached the end of list , then you will attempt to get() same item from pointList again and you will be reading off the end of the list, causing the exception. 如果从pointList删除最后一项,并且尚未到达list的末尾,那么您将再次尝试从pointList获取相同的项目,并且您将读取列表的末尾,从而导致异常。 This is what shoebox639 noticed; 这就是shoebox639注意到的; if you break the inner loop after removing something, the decrement in the outer loop will fix the issue. 如果在删除内容后中断内部循环,外部循环中的减量将解决问题。

Because of the order of iteration, it is impossible to remove two elements from the same run through the loop- you're only considering the end of the list, so nothing beyond the current point in pointList is candidate for removal. 由于迭代的顺序,不可能通过循环从同一个运行中删除两个元素 - 您只考虑列表的结尾,因此除了pointList的当前点之外没有任何东西可以删除。 If you were to remove two elements at once, it would be possible to shorten the list to a degree that the next i is off the list, but that can't happen here. 如果你要一次删除两个元素,可以将列表缩短到下一个i不在列表中的程度,但这不可能在这里发生。 Watch out for it in other, similar loops, though. 但要注意其他类似的循环。

You may remove more then one element of the pointList in every run of the first loop (over the pointList). 您可以在第一个循环的每次运行中(通过pointList)删除pointList的多个元素。 Put a breackpoint in the line pointList.remove(i); 在行pointList.remove(i)中放置一个breackpoint; and step through your code with the debugger and you will see it. 并使用调试器逐步执行代码,您将看到它。

Instead of iterating over your list with an integer, use the for each construct supported by the Collections interface. 不要使用整数迭代列表,而是使用Collections接口支持的for each构造。

public void listOfExternalPoints(List<Point> list) { 
    for (Point pointListEntry : pointList) { 
        for (Point listEntry : list) { 
            if (pointListEntry == listEntry) { 
                pointList.remove(pointListEntry); 
            } 
        } 
    } 
}

I haven't debugged this, but it looks right to me. 我没有调试过这个,但它看起来对我来说。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM