Java的ArrayList中删除对象 - IndexOutOfBoundsException异常 [英] Java ArrayList remove object - IndexOutOfBoundsException

查看:643
本文介绍了Java的ArrayList中删除对象 - 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如何选择一个方法重载另一些人。


  

该阶段是:


  
  

      
  1. 第一阶段(§15.12.2.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 from char to int by java.

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

    解决方案

    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.

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

    The phases are:

    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.

    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. 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. 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 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.

    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天全站免登陆