当前位置: 首页 > news >正文

数组边遍历(for循环)边删除为什么删不干净 及三种实现删除的方法

文章目录

  • 1、为什么删不干净
  • 倒序删
  • 迭代器
  • lambda表达式删除

为什么说数组边for循环遍历边删除会出现删不干净的情况

1、为什么删不干净

先写一个例子:可以先猜一下控制台会打印出什么内容?

public class removeIterator {public static void main(String[] args) {//ArrayList的底层数据结构就是数组List<String>list=new ArrayList<>();list.add("aaa");list.add("bbb");list.add("ccc");list.add("ddd");for(int i=0;i<list.size();i++){list.remove(i);}System.out.println(list.toString());}
}

公布答案:
在这里插入图片描述
可以看到,并没有全部移除掉(猜对没?)。那这是为什么呢?

一开始,list中是这样的:
在这里插入图片描述

当移除下标为0的元素后,index+1=1,而元素bbb及之后的元素都向前移动了一位,如下图:
在这里插入图片描述
接下来要移除index==1位置上的元素,也就是移除ccc,移除ccc后,ddd的下标变为1,而index+1=2,即不会移除ddd,所以最后list剩下了bbb和ddd:
在这里插入图片描述

那么如何才可以稳定的删除呢,总结了以下三种方法:

倒序删

倒序删不会出现上面例子中元素数组位置改变的情况。

public class removeIterator {public static void main(String[] args) {List<String>list=new ArrayList<>();list.add("aaa");list.add("bbb");list.add("ccc");list.add("ddd");for(int i=list.size()-1;i>=0;i--){list.remove(i);}System.out.println(list.toString());}
}

结果:
在这里插入图片描述

迭代器

使用 Iterator.remove() 方法
简单介绍一下这个方法:

  1. Collection接口实现了Iterable接口,实现了Iterable接口的类可以拥有增强for循环
  2. Iterator的remove()方法优势
    如果知道删除项的准确位置,删除操作的开销小
    不能对正在被遍历的集合进行改变(add,remove,clear等操作),但是可以调用iterator中的remove方法进行删除
public class removeIterator {public static void main(String[] args) {List<String>list=new ArrayList<>();list.add("aaa");list.add("bbb");list.add("ccc");list.add("ddd");Iterator<String> it = list.iterator();while(it.hasNext()){it.next();it.remove();}System.out.println(list.toString());}
}-----结果-----
[]

注:如果还未调用next()或在上一次调用 next 方法之后已经调用了 remove 方法,再调用remove都会报IllegalStateException。

lambda表达式删除

上面使用迭代器的方式虽然能够正常的删除列表中的元素,但是不够优雅,因为要写好几行的遍历代码,显得略臃肿。能不能只用一行代码完成这个功能呢?答案是可以的——使用Lambda表达式:
删除指定条件的元素:

  public String getString(List<Integer> list) {if (list == null || list.isEmpty()) {return null;}list.removeIf(e -> isNotValid(e));return list.stream().map(String::valueOf).collect(Collectors.joining(","));}private static Boolean isNotValid(Integer in) {if (in == null) {//为空的为无效数字return true;}return false;}
//输入:[1,2,3,null,5,null,7]
//输出:"1,2,3,5,7"
http://www.lryc.cn/news/38795.html

相关文章:

  • 环境配置之Keepass
  • Java 电话号码的组合
  • MATLAB——将直接型转化为并联型和级联型
  • .NET Framework .NET Core与 .NET 的区别
  • carla与ros2的自动驾驶算法-planning与control算法开发与仿真
  • corn表达式
  • 推荐系统中对抗性机器学习-文献综述与未来发展整理分享
  • Proteus8.15安装教程
  • Shell 基本运算符
  • Linux基础命令-sed流编辑器
  • C语言笔试题(1)
  • 网络连接的三种模式
  • 大学模拟电路期末考试模拟题详解
  • C/C++内存管理讲解
  • 【Linux】网络原理
  • list模拟实现
  • CSS看这一篇就够啦,CSS基础大全,可用于快速回顾知识,面试首选
  • Canvas详细使用方法(一)
  • CentOS定时任务——crontab
  • C51---蓝牙模块---连接软件---控制LED灯
  • Linux 学习笔记——二、主机规划与磁盘分区
  • 麒麟服务器V10 版本 安装 Anaconda教程,也就是安装Python环境的教程(亲测有效)
  • 【3维视觉】网格细分Mesh Subdivision算法介绍(Loop, Catmull-Clark, Doo-Sabin)
  • 自学大数据第六天~HDFS命令
  • maven仓库的配置
  • 医院信息管理云平台源码 云HIS系统源码 4级电子病历系统
  • JS学习第9天——ES6中面向对象(类class、constructor构造函数、类的继承extends、super关键字、面向对象tab栏切换案例)
  • K8S核心秘术学习总纲
  • 【PTA-训练day27】L2-038 病毒溯源 + L2-039 清点代码库 + L2-040 哲哲打游戏
  • 新一代跨平台云备份工具Duplicacy