Java中ArrayList remove会遇到的坑
时间:2022-05-04
本文章向大家介绍Java中ArrayList remove会遇到的坑,主要内容包括前言、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
前言
平时最常用的莫过于ArrayList
和HashMap
了,面试的时候也是问答的常客。先不去管容量、负载因子什么的,就是简单的使用也会遇到坑。
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);
}
- hbase源码系列(九)StoreFile存储格式
- 如何确定恶意软件是否在自己的电脑中执行过?
- Carbondata源码系列(二)文件格式详解
- 挖洞经验 | 记一次针对Twitter(Periscope)API 的有趣挖洞经历
- 设计模式学习(二): 观察者模式 (C#)
- Carbondata源码系列(一)文件生成过程
- BoopSuite:基于Python编写的无线安全审计套件
- 设计模式学习(一):多用组合少用继承(C#)
- 在asp.net web api 2 (ioc autofac) 使用 Serilog 记录日志
- hbase源码系列(十三)缓存机制MemStore与Block Cache
- hbase源码系列(十四)Compact和Split
- 设计模式学习(四): 1.简单工厂 (附C#实现)
- 从头编写 asp.net core 2.0 web api 基础框架 (5) EF CRUD
- 从头编写 asp.net core 2.0 web api 基础框架 (4) EF配置
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- Java面试高频知识点汇总 网络协议专题
- 「Mysql优化大师一」mysql服务性能剖析工具
- FPGA设计心得(12)如何正确使用 in_system_ibert ?
- Java面试高频知识点汇总 垃圾回收(GC)机制专题
- Celery-分布式任务队列学习笔记
- Java面试高频知识点汇总 数据库专题
- Java面试高频知识点总结 Redis
- Java面试高频知识点总结 Spring
- 杂谈小程序
- pytest封神之路第四步 内置和自定义marker
- (译)SDL编程入门(3)事件驱动编程
- 一个简单的Angular search UI实现
- (译)SDL编程入门(2)在屏幕上显示图像
- 【Vue进阶】手把手教你在 Vue 中使用 JSX
- (译)SDL编程入门(1)Hello SDL