Java ArrayList 删除对象 - IndexOutOfBoundsException

2024-01-06

我试图从 ArrayList 中删除一个对象,但不断收到 IndexOutOfBounds 错误。现在有大量可用信息,为什么会发生这种情况迭代在 ArrayList 上去除时,但是我不会那样做。 例子:

 ArrayList<Character> a = new ArrayList<Character>();
 a.add('A');
 a.add('B');
 a.add('C');
 System.out.println(a);
 a.remove('A');
 System.out.println(a);

prints [A, B, C]然后失败:

java.lang.IndexOutOfBoundsException: Index: 65, Size: 3
    at java.util.ArrayList.rangeCheck(ArrayList.java:635)
    at java.util.ArrayList.remove(ArrayList.java:474)
    at b.<init>(b.java:23)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at bluej.runtime.ExecServer$3.run(ExecServer.java:746)

为什么会发生这种情况?

编辑以澄清这个问题不是重复的这个问题 https://stackoverflow.com/questions/32568261/how-to-avoid-java-lang-arrayindexoutofboundsexception:

这里发生的具体问题与迭代时删除元素时的常见问题无关。这是由于 ArrayList 超载造成的remove方法和自动类型转换char to int通过java。

这方面在另一个问题的回答中没有涉及。


有2个超载remove方法 -一个需要一个int作为索引 https://docs.oracle.com/javase/8/docs/api/java/util/List.html#remove-int-, and 一个需要一个Object https://docs.oracle.com/javase/8/docs/api/java/util/List.html#remove-java.lang.Object-,删除对象引用本身。

JLS 第 15.12.2 节 https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.2介绍了 Java 如何选择一种方法重载而不是另一种方法重载。

这些阶段是:

  1. 第一阶段(§15.12.2.2)执行重载决策不允许装箱或拆箱转换,或者使用变量arity方法调用。如果在此阶段没有找到适用的方法,则处理继续到第二阶段。

这保证了在 Java SE 5.0 之前的 Java 编程语言中有效的任何调用不会因为引入变量数量方法、隐式装箱和/或拆箱而被认为是不明确的。但是,变量 arity 方法(第 8.4.1 节)的声明可以更改为给定方法调用表达式选择的方法,因为变量 arity 方法在第一阶段被视为固定 arity 方法。例如,在已声明 m(Object) 的类中声明 m(Object...) 会导致某些调用表达式(例如 m(null))不再选择 m(Object),如 m(Object[] ) 更具体。

  1. 第二阶段(§15.12.2.3)执行重载决策同时允许装箱和拆箱,但仍然排除使用变量数量方法调用。如果在此阶段没有找到适用的方法,则处理继续到第三阶段。

这确保了如果方法可通过固定数量方法调用适用,则永远不会通过可变数量方法调用来选择该方法。

  1. 第三阶段(第 15.12.2.4 节)允许重载与可变数量方法、装箱和拆箱相结合。

(粗体强调我的)

这两种方法都适用于此,因为char可以晋升为int,但也可以将其装箱到Character, 匹配a的类型参数。但是Java会在任何需要装箱的方法之前单独选择promotion,所以'A'被提升为int,因此值为 65。

您可以将其显式转换为Character如果你想通过对象引用删除。

a.remove((Character) 'A');
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java ArrayList 删除对象 - IndexOutOfBoundsException 的相关文章

随机推荐