Java的ArrayList中删除对象 - IndexOutOfBoundsException异常 [英] Java ArrayList remove object - IndexOutOfBoundsException
问题描述
我想从一个ArrayList中删除对象,但我不断收到IndexOutOfBounds错误。现在有很多资料,为什么发生这种情况时,迭代在ArrayList中的同时去除,但是我没有这样做。
例如:
的ArrayList<性格>一个=新的ArrayList<性格>();
a.add('A');
a.add(B);
a.add('C');
的System.out.println(一);
a.remove('A');
的System.out.println(一);
打印 [A,B,C]
,然后失败:
java.lang.IndexOutOfBoundsException:指数:65,尺寸:3
在java.util.ArrayList.rangeCheck(ArrayList.java:635)
在java.util.ArrayList.remove(ArrayList.java:474)
在B<&初始化GT;(b.java:23)
在sun.reflect.NativeConstructorAccessorImpl.newInstance0(本机方法)
在sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
在sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
在java.lang.reflect.Constructor.newInstance(Constructor.java:526)
在bluej.runtime.ExecServer $ 3.run(ExecServer.java:746)
为什么会出现这种情况?
修改,以澄清这个问题不是<一个副本href=\"https://stackoverflow.com/questions/32568261/how-to-avoid-java-lang-arrayindexoutofboundsexception\">this问题:
这是这里存在的具体问题无关,而去掉迭代元素时做的常见问题。这是相当的重载ArrayList中引起删除
方法,并从字符
到自动类型转换INT
通过Java的。
这方面不涉及其他问题的答案。
有2重载删除
法 - 的一个接受一个 INT
作为索引和一个接受一个对象
,删除对象引用本身。
的JLS <第15.12.2 /一>涵盖的Java如何选择一个方法重载另一些人。
该阶段是:
- 第一阶段(§15.12.2.2)执行重载解析,而不允许拳击或拆箱转换,或使用可变元数方法调用。如果在接着该阶段的处理中没有找到适用方法继续到第二阶段。
这保证了是有效的在Java SE 5.0之前,Java编程语言的任何电话不会认为含糊不清引进的可变参数数量的方法,隐式装箱和/或拆箱的结果。然而,可变元数法(§8.4.1)的声明可以改变选择用于给定方法的方法调用前pression的方法中,因为可变的arity方法如在第一阶段中的固定元数的方法进行处理。例如,声明米(对象...),其中已经声明了米(对象)的类引起米(对象),以不再被选择为某些调用前pressions(如m-(空)),为m (对象[])是更具体的。
<醇开始=2>
第二阶段(§15.12.2.3)执行重载的同时允许装箱和拆箱,但仍precludes采用可变元数方法调用。如果在接着该阶段的处理中没有找到适用方法继续到第三阶段。
这确保了一个方法永远不会变,通过元数方法调用选择,如果它是通过适用固定元数的方法调用。
<醇开始=3>
第三阶段(§15.12.2.4)允许超载带有可变参数数量的方法,拳击,和拆箱相结合。
块引用>(粗体重点煤矿)
这两种方法都适用在这里,因为
字符
可提升到INT
,但它也可以是盒装到字符
,匹配A
的类型参数。但是Java将单独选择的推广,需要拳击任何方法之前,让'A'
提升为INT
,因此,值65。您可以显式转换为
字符
如果你想通过对象引用删除。a.remove((汉字)'A');
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);
prints
[A, B, C]
and then fails with: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)
Why is this happening?
EDIT to clarify this question is not a duplicate of this question:
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 fromchar
toint
by java.This aspect is not covered in the answer of the other question.
解决方案There are 2 overloaded
remove
methods -- one that takes anint
as an index, and one that takes anObject
, to remove the object reference itself.Section 15.12.2 of the JLS covers how Java chooses one method overload over another.
The phases are:
- 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.
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.
- 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.
- The third phase (§15.12.2.4) allows overloading to be combined with variable arity methods, boxing, and unboxing.
(bold emphasis mine)
Both methods are applicable here, because a
char
can be promoted to anint
, but it can also be boxed to aCharacter
, matchinga
's type parameter. But Java will choose promotion alone before any method that requires boxing, so'A'
is promoted toint
, hence the value 65.You can cast it explicitly to
Character
if you want to remove by object reference.a.remove((Character) 'A');
这篇关于Java的ArrayList中删除对象 - IndexOutOfBoundsException异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!