【问题标题】:Reversing list throws IndexOutOfBoundsException反转列表抛出 IndexOutOfBoundsException
【发布时间】:2020-05-11 02:14:57
【问题描述】:

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

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。为什么?以及如何解决方法?

【问题讨论】:

  • ArrayList为空时length-1的值是多少?
  • 改变你的策略:向后迭代原始列表,并添加到新列表中。要知道为什么会出现异常,请阅读 add() 的 javadoc。
  • 使用 Collections.reverse() 反转列表
  • 这就是你要找的东西:stackoverflow.com/questions/3962766/…
  • 投反对票,因为您没有提供有关您的实际问题的任何信息。您的代码缺少错误信息、堆栈跟踪、解释和实际导致崩溃的示例输入。请阅读How to Askminimal reproducible example,谢谢。

标签: java reverse indexoutofboundsexception


【解决方案1】:

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

}

【讨论】:

  • 虽然这可行,但它并不能解释为什么 OPs 代码会失败。这可能是 OP 首先询问的原因。
【解决方案2】:

说明

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

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

抛出:IndexOutOfBoundsException - 如果索引超出范围 (index &lt; 0 || index &gt; size())


修复

要修复您的代码并仍然采用这种方法,您首先必须通过使用垃圾数据(例如大量 nulls)预填充列表来确保列表已经具有所需的大小。然后做你想做的事情,但使用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],则添加32,最后添加1。这很容易实现:

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

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

注意

还有其他方法可以解决这个问题,Java 也已经为此提供了内置方法,如果您可以选择的话,即Collections.reverse(list)

例如,见How to get a reversed list view on a list in Java?

【讨论】:

    猜你喜欢
    • 2013-05-20
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-18
    • 1970-01-01
    • 2021-12-20
    相关资源
    最近更新 更多