Java ArrayList 删除对象 - IndexOutOfBoundsException [英] Java ArrayList remove object - IndexOutOfBoundsException

查看:22
本文介绍了Java ArrayList 删除对象 - IndexOutOfBoundsException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从 ArrayList 中删除一个对象,但我不断收到 IndexOutOfBounds 错误.现在有很多可用的信息,为什么在 迭代 ArrayList 同时删除 时会发生这种情况,但是我没有这样做.示例:

I am trying to remove an object from an ArrayList, but I keep getting an IndexOutOfBounds Error. Now there is plenty information available why this happens when iterating over the ArrayList while removing, however I'm not doing that. Example:

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

打印 [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)

为什么会这样?

编辑澄清这个问题不是这个问题的重复:

这里出现的具体问题与迭代时移除元素时的常见问题无关.而是由重载的ArrayList remove 方法和java 自动从charint 的类型转换造成的.

The specific problem that is occuring here has nothing to do with the usual problems when removing elements while iterating. It is rather caused by the overloaded ArrayList remove method and the automatic type conversion from char to int by java.

另一个问题的答案中没有涉及到这一方面.

This aspect is not covered in the answer of the other question.

推荐答案

有 2 个重载的 remove 方法 -- int 作为索引一个接受 Object,删除对象引用本身.

There are 2 overloaded remove methods -- one that takes an int as an index, and one that takes an Object, to remove the object reference itself.

第 15.12.2 节JLS 介绍了 Java 如何选择一种方法重载而不是另一种方法重载.

Section 15.12.2 of the JLS covers how Java chooses one method overload over another.

阶段是:

  1. 第一阶段(第 15.12.2.2 节)执行重载解析不允许装箱或拆箱转换,或使用可变数量方法调用.如果在此阶段未找到适用的方法,则处理继续到第二阶段.
  1. The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase.

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

This guarantees that any calls that were valid in the Java programming language before Java SE 5.0 are not considered ambiguous as the result of the introduction of variable arity methods, implicit boxing and/or unboxing. However, the declaration of a variable arity method (§8.4.1) can change the method chosen for a given method method invocation expression, because a variable arity method is treated as a fixed arity method in the first phase. For example, declaring m(Object...) in a class which already declares m(Object) causes m(Object) to no longer be chosen for some invocation expressions (such as m(null)), as m(Object[]) is more specific.

  1. 第二阶段(第 15.12.2.3 节)执行重载决议同时允许装箱和拆箱,但仍排除使用可变数量方法调用.如果在此阶段未找到适用的方法,则处理继续到第三阶段.
  1. The second phase (§15.12.2.3) performs overload resolution while allowing boxing and unboxing, but still precludes the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the third phase.

如果某个方法适用于固定数量方法调用,则这可确保永远不会通过可变数量方法调用选择该方法.

This ensures that a method is never chosen through variable arity method invocation if it is applicable through fixed arity method invocation.

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

(粗体强调我的)

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

Both methods are applicable here, because a char can be promoted to an int, but it can also be boxed to a Character, matching a's type parameter. But Java will choose promotion alone before any method that requires boxing, so 'A' is promoted to int, hence the value 65.

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

You can cast it explicitly to Character if you want to remove by object reference.

a.remove((Character) 'A');

这篇关于Java ArrayList 删除对象 - IndexOutOfBoundsException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆