【问题标题】:java.util.ArrayList length and size different?java.util.ArrayList 长度和大小不同?
【发布时间】:2021-12-28 19:01:15
【问题描述】:

我收到关于以下代码行的定期崩溃报告:

myList.get(myList.size() - 1)

如果没有堆栈跟踪,这不会那么有趣:

java.lang.ArrayIndexOutOfBoundsException: length=22; index=-1
java.util.ArrayList.get ArrayList.java:439
com.myapp.ope.api.ApiManager$2.onResponse ApiManager.java:215
retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall$1.lambda$onResponse$0$DefaultCallAdapterFactory$ExecutorCallbackCall$1 DefaultCallAdapterFactory.java:89
retrofit2.-$$Lambda$DefaultCallAdapterFactory$ExecutorCallbackCall$1$hVGjmafRi6VitDIrPNdoFizVAdk.run Unknown Source:6

这似乎暗示 myList 的长度为 22。那么如何在 -1 处计算索引(这意味着 .size() 会报告 0)?

【问题讨论】:

  • 所以是的,列表的大小为 0,其中包含 0 个项目,并且您试图在索引 -1 处获取项目,这显然是行不通的。我之前没有在此错误消息上下文中看到术语“长度”,并且不确定它的含义,但它不会改变导致错误的重要事实。
  • @HovercraftFullOfEels,啊。因此,我明白了,在这种情况下,“长度”并不意味着大小。我认为它确实意味着大小,并且不知何故,大小在 .size() 调用和 .get() 调用之间发生了变化。
  • 一个 ArrayList 并没有真正的“长度”(我知道)。它有一个容量,它是它的后备数组的长度,其中一些可能为空的项目,以及一个大小,它拥有多少个实际对象。在这里,大小才是最重要的。
  • 我的意思是,在此错误消息的上下文中,它非常清楚地意味着 ArrayList 用作存储的内部数组的长度。
  • @LouisWasserman,那么当 .size 在同一行报告为 0 时,内部数组长度是 22 吗?

标签: java android retrofit2


【解决方案1】:

Java 8 中的ArrayList 仅检查索引是否大于其大小,如果是则抛出IndexOutOfBoundsException。否则array[index] 用于访问用于存储列表元素的数组的所需元素。如果索引超出范围,这将使用消息中数组的长度抛出ArrayIndexOutOfBoundsException。如果需要,该数组将被更大的数组替换,但永远不会更改为更小的数组 - 因此数组大于所需的数组是正常的。

在 Java 9 中,索引检查发生了变化:它使用 Objects.checkIndex(),它检查限制并使用列表的大小来获取异常消息。

【讨论】:

    【解决方案2】:

    ArrayList 在内部由一个数组支持,它会根据需要动态调整内部数组,并且 size 变量在您添加元素时保持不变(添加元素时递增,删除元素时递减)。

    假设ArrayList的底层数组长度为22(可能是空数组,即没有存储元素),当您尝试使用-1索引访问它时,它会抛出java.lang.ArrayIndexOutOfBoundsException

    *在访问列表之前尝试打印列表大小以及查看大小是否为 0

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-10-01
      • 2016-02-29
      • 2017-06-23
      • 1970-01-01
      • 2018-12-11
      • 1970-01-01
      • 2021-11-30
      相关资源
      最近更新 更多