前言

平时最常用的莫过于ArrayListHashMap了,面试的时候也是问答的常客。先不去管容量、负载因子什么的,就是简单的使用也会遇到坑。

Remove 元素

经常遇到的一个场景是:遍历list, 然后找到合适条件的给删除掉,比如删除所有的偶数。

@Test
public void testRemove2(){
List<Integer> integers = new ArrayList<>(5);
integers.add(1);
integers.add(2);
integers.add(2);
integers.add(4);
integers.add(5); for (int i = 0; i < integers.size(); i++) {
if (integers.get(i)%2==0){
integers.remove(i);
}
} System.out.println(integers);
}

看起来好像没问题,加入面试的时候当面问:输出结果是什么?再问真不会报错吗?再问结果是什么?

  • 报错
  • 结果是空list
  • 结果是[1, 2, 5]

List.remove()有两个,一个 public E remove(int index),一个是public boolean remove(Object o) ,那下面的结果是什么:

@Test
public void testRemove(){
ArrayList<Integer> integers = Lists.newArrayList(1, 2, 3, 4);
System.out.println(integers);
integers.remove(1);
System.out.println(integers);
}
  • [1, 3, 4]

经常会使用一个Arrays.asList的API, 那么下面的结果是什么:

@Test
public void testRemove3(){
List<String> list = Arrays.asList("a","b");
list.add("c");
System.out.println(list);
}
  • 报错: java.lang.UnsupportedOperationException

使用foreach是否可以实现刚开始的问题

@Test
public void testRemove4(){
List<String> strings = new ArrayList<>();
strings.add("a");
strings.add("b");
strings.add("c");
strings.add("d"); for (String string : strings) {
strings.remove(string);
}
}
  • 否,报错java.util.ConcurrentModificationException

为了性能问题,我们推荐把list.size的计算提取出来

@Test
public void testRemove5(){
List<String> strings = new ArrayList<>();
strings.add("a");
strings.add("b");
strings.add("c");
strings.add("d"); int size = strings.size();
for (int i = 0; i < size; i++) {
strings.remove(i);
} }
  • 报错: java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
  • 这是很好的习惯, 不像开头那样每次循环都计算一次size,而且按这种情况还可以再运行的时候报错。文初的做法不报错,但结果并不是我们想要的。

使用Iterator是不是就可以remove了


@Test
public void testRemove6(){
List<String> strings = new ArrayList<>();
strings.add("a");
strings.add("b");
strings.add("c");
strings.add("d"); Iterator<String> iterator = strings.iterator();
while (iterator.hasNext()){
String next = iterator.next();
strings.remove(next);
} System.out.println(strings);
}
  • 报错: java.util.ConcurrentModificationException

正确的remove做法是什么

@Test
public void testRemove7(){
List<String> strings = new ArrayList<>();
strings.add("a");
strings.add("b");
strings.add("c");
strings.add("d"); Iterator<String> iterator = strings.iterator();
while (iterator.hasNext()){
String next = iterator.next();
iterator.remove();
} System.out.println(strings);
}

Java中ArrayList remove会遇到的坑的更多相关文章

  1. [Java基础] Java中List.remove报错UnsupportedOperationException

    Java中List.remove(removeRange,clear类似) 报出 UnsupportedOperationException 的错误.原来该List是一个AbstractList,不支 ...

  2. java中ArrayList 、LinkList区别

    转自:http://blog.csdn.net/wuchuanpingstone/article/details/6678653 个人建议:以下这篇文章,是从例子说明的方式,解释ArrayList.L ...

  3. JAVA中ArrayList用法

    JAVA中ArrayList用法 2011-07-20 15:02:03|  分类: 计算机专业 |  标签:java  arraylist用法  |举报|字号 订阅     Java学习过程中做题时 ...

  4. Java中arraylist和linkedlist源代码分析与性能比較

    Java中arraylist和linkedlist源代码分析与性能比較 1,简单介绍 在java开发中比較经常使用的数据结构是arraylist和linkedlist,本文主要从源代码角度分析arra ...

  5. Java中ArrayList与LinkedList的区别

    Java中ArrayList与LinkedList的区别 一般大家都知道ArrayList和LinkedList的区别: 1. ArrayList的实现是基于数组,LinkedList的实现是基于双向 ...

  6. java中ArrayList 和 LinkedList 有什么区别

    转: java中ArrayList 和 LinkedList 有什么区别 ArrayList和LinkedList都实现了List接口,有以下的不同点:1.ArrayList是基于索引的数据接口,它的 ...

  7. Java中ArrayList循环遍历并删除元素的陷阱

    ava中的ArrayList循环遍历并且删除元素时经常不小心掉坑里,昨天又碰到了,感觉有必要单独写篇文章记一下. 先写个测试代码: import java.util.ArrayList; public ...

  8. Java中ArrayList的自我实现

    对于ArrayList相比大家都很熟悉,它是java中最常用的集合之一.下面就给出它的自我实现的java代码. 需要说明的一点是,它是基于数组创建的.所以它在内存中是顺序存储,对于查找十分的方便. p ...

  9. Java中ArrayList相关的5道面试题

    本文参考了 <关于ArrayList的5道面试题 > 1.ArrayList的大小是如何自动增加的? 这个问题我想曾经debug过并且查看过arraylist源码的人都有印象,它的过程是: ...

随机推荐

  1. MongoDB备份和恢复

    mongodump备份数据 该命令可以导出所有数据到指定目录中, 也能通过参数指定备份服务器 mongodump -h dbhost -d dbname -o dbdirectory dbhost: ...

  2. swift3.0 对UITextField()输入框输入的内容进行监控

    首先需要继承 UITextFieldDelegate class TestViewController: UIViewController,UITextFieldDelegate{ } 添加事件委托 ...

  3. hdu--1013--Digital Roots(字符串)

    Digital Roots Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tot ...

  4. 【思维】【水】 南阳oj 喷水装置(一)

    描述 现有一块草坪,长为20米,宽为2米,要在横中心线上放置半径为Ri的喷水装置,每个喷水装置的效果都会让以它为中心的半径为实数Ri(0<Ri<15)的圆被湿润,这有充足的喷水装置i(1& ...

  5. ios UIButton改背景

    以下orangeButton.png与orangeButtonHighlight.png分别用于按钮平常状态和被点击时的状态: UIImage *buttonImage = [[UIImage ima ...

  6. 今天聊一聊nuxt.js(上)

    背景 近期在做内部系统的重构,从一线业务彻底的重构,经过充分的考虑我们准备把这个项目打造成前台业务的试验站,比如ssr和一些其他的前沿技术的探索,积累充分的经验后待合适的契机应用到C端的项目中. 既然 ...

  7. Android -- 从源码的角度一步步打造自己的TextView

    1,自定义控件一直是我们的痛点,今天就和大家一点点去了解了解,首先一般的自定义控件都是继承于View类,所以我们先来看看view的一些重要的方法,这是官方文档,大家想了解更多也可以去看看,这里我展示对 ...

  8. ECharts的简单使用

    ECharts,一个纯 Javascript 的图表库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari等),底层依赖轻 ...

  9. angular学习(二)-- Directive

    1.2 指令:Directive AngularJS 通过被称为 指令 的新属性来扩展 HTML, 具体表现形式一般为带有前缀 ng-xxx 的 HTML 属性. 指令的使用形式 ng-xxx 的属性 ...

  10. mysql explain和profiling

    语法:explain  select .... 变体: 1.explain extended select .... 将执行计划“反编译”成select语句: 运行show warnings 可以得到 ...