繁体   English   中英

反转列表抛出 IndexOutOfBoundsException

[英]Reversing list throws IndexOutOfBoundsException

该方法应该颠倒列表中项目的顺序

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 为什么? 以及如何修复该方法?

解释

您的代码的主要问题是您假设您可以使用add(index, element)直接将某些内容添加到ArrayList的后面位置。

但它不是一个数组,它是一个列表。 这不可能。 add方法不允许添加超过其当前大小的内容当前大小仍为0 如此方法的文档中所述:

抛出: IndexOutOfBoundsException - 如果索引超出范围(index < 0 || index > size())


使固定

要修复您的代码,并且仍然采用这种方法,您首先必须通过用垃圾数据(如大量null预填充列表来确保列表已经具有所需的大小。 然后做你想做的事,但使用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 中的列表上获取反向列表视图?

使用 for-loop() 反转列表中项目顺序的另一种替代方法可能是:

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;
    }

}

暂无
暂无

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

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