Список реверсирования генерирует исключение IndexOutOfBoundsException - PullRequest
0 голосов
/ 24 января 2020

Предполагается, что метод меняет порядок элементов в списке

public class ZrcalnaSlikaSeznama {
    public static <T> List<T> zrcalnaSlika(List<T> seznam) {
        int length = seznam.size();
        List<T> seznam2 = new ArrayList<>();
        for (T x : seznam){
            seznam2.add(length-1, x);
            length--;
        }
        return seznam2;
    }
}

Но он выдает IndexOutOfBoundsException. Почему? А как исправить метод?

Ответы [ 2 ]

1 голос
/ 24 января 2020

Объяснение

Основная проблема вашего кода заключается в том, что вы предполагали, что можете напрямую добавить что-то на более позднюю позицию в ArrayList, используя add(index, element).

Но это не так массив, это список. Это невозможно. Метод add не позволяет добавлять сверх его текущего размера , который по-прежнему равен 0. Как объяснено в документации этого метода:

Броски: IndexOutOfBoundsException - если индекс выходит за пределы диапазона (index < 0 || index > size())


Fix

Чтобы исправить ваш код и продолжать этот подход, вы должны сначала убедиться, что список уже имеет желаемый размер, предварительно заполнив его данными для мусора, например, большим количеством null s. И затем делать то, что вы пытались сделать, но с помощью set, а не add (иначе вы не изменили бы существующие записи, а изменили бы их). Итак, что-то вроде этого:

List<T> reversed = new ArrayList<>();

// Fill with garbage
for (int i = 0; i < seznam.size(); i++) {
    reversed.add(null);
}

// Exchange against elements
int i = seznam.size() - 1;
for (T element : seznam) {
    reversed.set(i, element);
    i--;
}

Правильное решение

Очевидно, что заполнение списка сначала данными для мусора - не идеальный подход. Вы можете сделать намного лучше. Как насчет добавления в ваш новый список вперед, но итерации исходных элементов в обратном направлении. Поэтому, если у вас есть [1, 2, 3], вы добавляете 3, 2 и, наконец, 1. Это может быть легко достигнуто:

List<T> reversed = new ArrayList<>();

for (int i = seznam.size() - 1; i >= 0; i--) {
    reversed.add(seznam.get(i));
}

Примечание

Есть и другие подходы к этому, и Java также имеет встроенные методы для этого, если это вариант для вас, например Collections.reverse(list).

Например, см. Как получить перевернутый вид списка в списке в Java?

0 голосов
/ 24 января 2020

Другая альтернатива для изменения порядка элементов в Списке с помощью for-l oop () может быть:

public class ZrcalnaSlikaSeznama {

    public static <T> List<T> zrcalnaSlika(List<T> seznam) {
        int length = seznam.size();
        List<T> seznam2 = new ArrayList<>();

        for (int i = length-1; i>=0; i--){
            seznam2.add(seznam.get(i));
        }

        return seznam2;
    }

}
...