public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<Integer> arr = new ArrayList<Integer>();
for(int i = 10;i<15;i++)
arr.add(i);
arr.remove(10); }
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 10, Size: 5
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.remove(ArrayList.java:387)
at string.testArrayListRemove.main(testArrayListRemove.java:15)

对arr进行移除“10”这个元素时,报越界异常。

原因是传入的参数10被当成索引而不是要移除的元素。查阅api发现remove有两个方法

public E remove(int index)
移除此列表中指定位置上的元素。向左移动所有后续元素(将其索引减 1)。 public boolean remove(Object o)
移除此列表中首次出现的指定元素(如果存在)。如果列表不包含此元素,则列表不做改动。更确切地讲,移除满足 (o==null ? get(i)==null : o.equals(get(i))) 的最低索引的元素(如果存在此类元素)。如果列表中包含指定的元素,则返回 true(或者等同于这种情况:如果列表由于调用而发生更改,则返回 true)。

下面这种操作方式就行了。

        ArrayList<Integer> arr = new ArrayList<Integer>();
for(int i = 10;i<15;i++)
arr.add(i);
// arr.remove(10);
arr.remove((Integer)10);
        ArrayList<Integer> arr = new ArrayList<Integer>();
for(int i = 10;i<15;i++)
arr.add(i);
int arrSize = arr.size();
for(int i = 0;i<arrSize;i++)
if(10 == arr.get(i))
arr.remove(i);

上面这段代码也执行不了,也报越界异常。

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 4, Size: 4
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.get(ArrayList.java:322)
at string.testArrayListRemove.main(testArrayListRemove.java:17)
        ArrayList<Integer> arr = new ArrayList<Integer>();
for(int i = 10;i<15;i++)
arr.add(i);
arr.add(10);
arr.add(10);
arr.add(10);
arr.add(10);
arr.add(11);
System.out.println("删除前:"+arr.size());
for(int i = 0;i<arr.size();i++)
if(10 == arr.get(i))
arr.remove(i);
System.out.println("删除后:"+arr.size());

仔细看下执行结果:

删除前:10
删除后:7

arraylist进行remove操作会产生上面两种情况呢?

原因是每次remove后的size都会发生变化,但是迭代基数没有根据remove后的size动态调整,导致越界及集合遍历不完全。

正确方法如下:

        ArrayList<Integer> arr = new ArrayList<Integer>();
for(int i = 10;i<15;i++)
arr.add(i);
arr.add(10);
arr.add(10);
arr.add(10);
arr.add(10);
arr.add(11);
System.out.println("删除前:"+arr.size());
for(int i = 0;i<arr.size();i++){ if(10 == arr.get(i)){ arr.remove(i);
i--;
} } System.out.println("删除后:"+arr.size());

在remove操作后,将索引位置-1,

或者是用迭代器。

        ArrayList<Integer> arr = new ArrayList<Integer>();
for(int i = 10;i<15;i++)
arr.add(i);
arr.add(10);
arr.add(10);
arr.add(10);
arr.add(10);
arr.add(11);
System.out.println("删除前:"+arr.size());
Iterator<Integer> it = arr.iterator();
while(it.hasNext()){
if(10 == it.next())
it.remove();
}

关于arraylist.remove的一些小问题。的更多相关文章

  1. JAVA之旅(十九)——ListIterator列表迭代器,List的三个子类对象,Vector的枚举,LinkedList,ArrayList和LinkedList的小练习

    JAVA之旅(十九)--ListIterator列表迭代器,List的三个子类对象,Vector的枚举,LinkedList,ArrayList和LinkedList的小练习 关于数据结构,所讲的知识 ...

  2. ArrayList中的一些小细节@JDK8

    ArrayList中的一些小细节@JDK8 protected transient int modCount = 0; 该变量用于记录ArrayList的版本号,不可被序列化,每次对ArrayList ...

  3. List<Integer>.remove()的一个小细节

    不废话,先上代码: ArrayList<Integer> col = new ArrayList<Integer>(); System.out.println("In ...

  4. Java中ArrayList remove会遇到的坑

    前言 平时最常用的莫过于ArrayList和HashMap了,面试的时候也是问答的常客.先不去管容量.负载因子什么的,就是简单的使用也会遇到坑. Remove 元素 经常遇到的一个场景是:遍历list ...

  5. C# ArrayList的使用方法小总结

    1.什么是ArrayList ArrayList就是传说中的动态数组,用MSDN中的说法,就是Array的复杂版本,它提供了如下一些好处: 动态的增加和减少元素 实现了ICollection和ILis ...

  6. 为什么ArrayList remove报错

    不报错 List<String> userNames = new ArrayList<String>() {{ add("Hollis"); add(&qu ...

  7. ArrayList remove注意事项

    例子1: List<Integer>list=new ArrayList<>(); list.add(1); list.add(2); list.add(2); list.ad ...

  8. java ArrayList remove 2 及正确方法

    https://www.cnblogs.com/chrischennx/p/9610853.html 正确方式 方法一,还是fori,位置前挪了减回去就行了, remove后i--: public v ...

  9. java ArrayList remove

    packimport java.util.ArrayList;import java.util.List; public class ArrayListRemove { public static v ...

随机推荐

  1. Ehcache(04)——设置缓存的大小

    http://haohaoxuexi.iteye.com/blog/2116749 设置缓存的大小 目录 1     CacheManager级别 2     Cache级别 3     大小衡量 4 ...

  2. Java IO之File

    FILE类是用来实现获取文件.文件夹的类库工具,File并不是像类名所表示的那样仅仅是用来表示文件.它还能够用来表示文件夹. 所以能够用File来获取一个文件夹下的全部文件,甚至是文件夹中的文件. 一 ...

  3. linux 内核参数图解

    https://www.suse.com/documentation/sles11/book_sle_tuning/data/part_tuning_kernel.html http://blog.c ...

  4. Session丢失,都是CDN惹的祸

    周六下午,正在外面吃饭,运营的同事火急火燎地给我打电话,说是网站出问题了,用户登录不了,而且这种情况也不是全部,只有部分地区有问题.没办法,只能回到家里找问题,打开代码,翻来覆去地找问题,搞了整整一下 ...

  5. QT核心编程之调试技术 (g)

    Qt应用程序的调试可以通过DDD进行跟踪调试和打印各种调试或警告信息.DDD(Data Display Debugger)是使用gdb调试工具的图形工具,它安装在Linux操作系统中,使用方法可参考D ...

  6. PHP Fuzzing行动——源码审计

    目录: Section 1: 20种PHP源码快速审计方式  Section 2: PHP源码审计自动化( PHP Fuzzer )  风险级别: ■ Low ■ Medium ■ High   在开 ...

  7. C#中的预处理器指令详解

    这篇文章主要介绍了C#中的预处理器指令详解,本文讲解了#define 和 #undef.#if.#elif.#else和#endif.#warning和#error.#region和#endregio ...

  8. 认识C中的结构体

    C中结构体是另外一种表示数据形式的方式,结构体中可以表示C中的基本数据形式,如int,double....结构体可以让我们更好的表示数据.下面来看看结构体. 说到结构体首先要了解的是它的申明形式,要申 ...

  9. IOS 从系统图库中获取 图片 并设置为头像

    总会遇到一些应用 要拍照 设置图片之类的的  总结一个方法备用  以后 会 继续拓展到 多图 @interface AddCustomerViewController : UIViewControll ...

  10. C#高级特性

    1.接口 接口与抽象基类.抽象类与接口的不同是,抽象类不仅可以定义多态接口还可以定义一些其他的成员以及构造函数.而接口只能包含抽象成员. 抽象父类创建多态接口,只有派生类才可以.而往往很多情况下非派生 ...