IndexOutOfBoundsException - PullRequest
       1

IndexOutOfBoundsException

2 голосов
/ 24 ноября 2010

Привет, этот код вернет indexoutofboundsException, и действительно, я не знаю, почему?Я хочу удалить из 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--;
            }
        }
    }

}

. Кроме того, вывод println будет:

54
62

Также исключение:

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)

спасибо.

Ответы [ 7 ]

10 голосов
/ 24 ноября 2010

эй, вы удалили некоторые элементы из списка. Таким образом, список меньше, чем он был в начале цикла.

Я предлагаю вам использовать:

pointList.removeAll(list)

Или итератор.

6 голосов
/ 24 ноября 2010

Когда вы делаете pointList.remove(i), вы должны выйти из внутреннего цикла.В противном случае он попытается проиндексировать pointList.get(i), который вы только что удалили, снова на следующей итерации цикла, поэтому вы получаете исключение.

Когда arrayLists удаляет элементы, этот элемент удаляетсяи все элементы после него сдвигаются вниз.Таким образом, если вы удалите индекс 3 и в нем будет только 4 элемента, новый массив arrayList будет иметь только размер 3, и вы попытаетесь получить индекс 3, выходящий за пределы.

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

Он будет иметь такую ​​же эффективность, но, думаю, более корректно.Помните, что == сравнивает ссылки для одного и того же объекта.Где в качестве метода удаления используются .equals для проверки на равенство, что, как я полагаю, вы хотите.

2 голосов
/ 24 ноября 2010

pointList.remove (i);

Это уменьшит ваш размер pointList.Надеюсь, это поможет.

1 голос
/ 24 ноября 2010

Удаление объекта из pointList уменьшит его размер.Поэтому в одной итерации блока «для j» вы можете удалить два элемента PointList, сместив все остальные элементы влево.Однако в следующей итерации «i» будет ссылаться на местоположение вне границ (60).

0 голосов
/ 24 ноября 2010

Вы можете удалить более одного элемента pointList при каждом запуске первого цикла (через pointList).Поместите точку взлома в строку pointList.remove (i);и пошагово пройдитесь по коду с помощью отладчика, и вы увидите его.

0 голосов
/ 24 ноября 2010

Проблема с порядком оценки цикла.Вы только один раз оцениваете длину pointList и никогда не проверяете ее снова.

Если вы удалили последний элемент из pointList и не достигли конца list, вы попытаетесьСнова получите () тот же элемент из pointList, и вы будете читать в конце списка, вызывая исключение.Это то, что заметил shoebox639;если вы прервете внутренний цикл после удаления чего-либо, декремент во внешнем цикле решит проблему.

Из-за порядка итерации невозможно удалить два элемента из одного цикла через цикл - выВы рассматриваете только конец списка, поэтому ничего, кроме текущей точки в pointList, не может быть удалено.Если бы вы удалили два элемента одновременно, можно было бы сократить список до такой степени, что следующий i не будет в списке, но здесь этого не может быть.Остерегайтесь этого в других, подобных петлях, хотя.

0 голосов
/ 24 ноября 2010

Вместо того, чтобы перебирать свой список с целым числом, используйте для каждой конструкции, поддерживаемой интерфейсом Коллекции.

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

Я не отлаживал это, но мне это кажется правильным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...