1. 简介

有时候需要在集合遍历过程中进行增/删,下面介绍几种正确的操作方式。

2. 示例

例如有如下集合[1, 2, 2, 3, 5],需要删除被2整除的元素。

 import java.util.*;

 public class ListFunc2 {

     public static void main(String[] args){
String str = "12235";
String[] arr = str.split("");
List<String> list1 = new ArrayList<>(Arrays.asList(arr));
List<String> list2 = new ArrayList<>(Arrays.asList(arr));
List<String> list3 = new ArrayList<>(Arrays.asList(arr));
List<String> list4 = new ArrayList<>(Arrays.asList(arr));
List<String> list5 = new ArrayList<>(Arrays.asList(arr));
List<String> list6 = new ArrayList<>(Arrays.asList(arr)); System.out.println(list1); // [1,2,2,3,5]

2.1 正序方式

从集合的第一个元素开始遍历:

 // 正序方式
for(int i=0; i<list2.size(); i++){
int value = Integer.parseInt(list2.get(i));
if(value%2==0){
list2.remove(i);
}
}
System.out.println(list2); // [1, 2, 3 ,5]

发现未完全删除可以被2整除的元素,原因如下:当i=1时删除第二个元素2,此时后面的元素会前移;然而下次遍历时索引i=2,

对应的元素为3,跳过了原集合中的第三个元素2。

0      3  4   // index
1 2 2 3 5
1 2 5

此时尝试对索引进行修正,将索引重新指向原集合的第三个元素:

 for(int i=0; i<list3.size(); i++){
int value = Integer.parseInt(list3.get(i));
if(value%2==0){
list3.remove(i);
i--; // 修正
}
}
System.out.println(list3); // [1, 3, 5]

2.2 逆序方式

从集合的最后一个元素开始向前遍历:

 // 逆序方式
for(int i= list4.size()-1; i>=0; i--){
int value = Integer.parseInt(list4.get(i));
if(value%2==0){
list4.remove(i);
}
}
System.out.println(list4); // [1, 3, 5]

索引和集合的对应变化过程如下:

当索引为2时,删除集合中的第三个元素2,此时集合中的后续元素前移;然后索引变为1,删除集合中的第二个元素2;

可以发现,后续元素的前移不会导致索引的跳跃,不影响前面的元素。

0      3  4     // index
1 2 3 5
1 3 5

2.3 Iterator方式

推荐使用Iterator对遍历过程中的集合进行修改,不用担心索引的跳跃和越界情况。

 // iterator迭代器
for(Iterator<String> it = list5.iterator(); it.hasNext();){
int value = Integer.parseInt(it.next());
if(value%2==0){
it.remove();
}
}
System.out.println(list5); // [1, 3, 5] Iterator<String> it = list6.iterator();
while(it.hasNext()){
int value = Integer.parseInt(it.next());
if(value%2==0){
it.remove();
}
}
System.out.println(list6); // [1, 3, 5]

2.4 Java 8 新特性

直接使用boolean removeIf(Predicate<? super E> filter)方法

 // java 8最新方法
list1.removeIf(v->Integer.parseInt(v)%2==0); // v表示集合中的元素,给出适当条件过滤
System.out.println(list1); // [1, 3, 5]

!!!

java 动态增/减集合元素的更多相关文章

  1. Java使用foreach遍历集合元素

    Java使用foreach遍历集合元素 1.实例源码 /** * @Title:ForEach.java * @Package:com.you.model * @Description:使用forea ...

  2. 恕我直言你可能真的不会java第10篇-集合元素归约

    Stream API为我们提供了Stream.reduce用来实现集合元素的归约.reduce函数有三个参数: Identity标识:一个元素,它是归约操作的初始值,如果流为空,则为默认结果. Acc ...

  3. java 自增/减运算符

    注意:python中没有 一.自增运算符 1.单独使用时,目的获取变量的值,前++和后++没有区别,使用后值都会递增一. 2.混合使用时,才有区别.前++,先加后用.后++,先用后加 二.自减运算符 ...

  4. Java依据集合元素的属性,集合相减

    两种方法:1.集合相减可以使用阿帕奇的一个ListUtils.subtract(list1,list2)方法,这种方法实现必须重写集合中对象的属性的hashCode和equals方法,集合相减判断的会 ...

  5. java数组集合元素的查找

    java数组和集合的元素查找类似,下面以集合为例. 数组集合元素查找分为两类: 基本查找: 二分折半查找: 基本查找: 两种方式都是for循环来判断,一种通过索引值来判断,一种通过数组索引判断. 索引 ...

  6. 重写Java Object对象的hashCode和equals方法实现集合元素按内容判重

    Java API提供的集合框架中Set接口下的集合对象默认是不能存储重复对象的,这里的重复判定是按照对象实例句柄的地址来判定的,地址相同则判定为重复,地址不同不管内容如何都判定为不重复,这有时与需求不 ...

  7. Java集合——遍历集合元素并修改

    Java集合——遍历集合元素并修改 摘要:本文主要总结了遍历集合的方式,以及在遍历时修改集合要注意的问题. 遍历Collection 对List和Set的遍历,有四种方式,下面以ArrayList为例 ...

  8. Java修炼——ArrayList常用的方法以及三种方式遍历集合元素。

    List接口ArrayList用法详解 ArrayList常用方法: 1. List.add():添加的方法(可以添加字符串,常量,以及对象) List list=new ArrayList(); l ...

  9. java 数据类型:集合接口Collection之常用ArrayList;lambda表达式遍历;iterator遍历;forEachRemaining遍历;增强for遍历;removeIf批量操作集合元素(Predicate);

    java.util.Collection接口 Java的集合主要由两个接口派生出来,一个是Collection一个是Map,本章只记录Collection常用集合 集合只能存储引用类型数据,不能存储基 ...

随机推荐

  1. C#WFM关于PICBOX 再DIP界面放大125%后,图片显示不完整

    外观哪里选中Zoom,就好

  2. cxf整合spring中出现的错误

    Caused by: java.lang.ClassNotFoundException: javax.wsdl.extensions.ElementExtensible at org.apache.c ...

  3. PLS-00357: Table,View Or Sequence reference 'SEQ_TRADE_RECODE.NEXTVAL' not allowed in this context

    oracle数据库: 为了使ID自增,建了序列后,创建触发器: create or replace TRIGGER TRIG_INSERT_TRADE_RECODE BEFORE INSERT ON ...

  4. Windows 安装配置MongoDB

    1.安装 下载安装包 直接下一步. 2.添加环境变量 3.bin同级目录下新建data文件夹,data文件夹下新建db和log文件夹 4.输入命令启动mongodb服务 mongod --dbpath ...

  5. 用keytool制作证书并在tomcat配置https服务(一)

    https分为单项认证和双向认证. 一般https页面上的访问都是单项认证,服务端发送数字证书给客户端,客户单方面验证.而服务端不做验证. 而双向认证,需要双方都有证书,然后发送给对方进行验证.一般用 ...

  6. JS引擎的执行机制:探究EventLoop(含Macro Task和Micro Task)

    在我看来理解好JS引擎的执行机制对于理解JS引擎至关重要,今天将要好好梳理下JS引擎的执行机制. 首先解释下题目中的名词:(阅读本文后你会对这些概念掌握了解) Event Loop:事件循环Micro ...

  7. topcoder srm 615 div1

    problem1 link 对于数字$x$,检验每个满足$x=y*2^{t}$的$y$能否变成$x$即可. problem2 link 如果起点到终点有一条长度为$L$的路径,那么就存在长度为$L+k ...

  8. 软考自查:数据流图(DFD)

    数据流图(DFD) 内容提要 数据流图基本概念 数据字典 数据平衡原则 数据流图基本概念             数据字典     数据流图平衡原则 父图与子图之间的平衡 子图内平衡         ...

  9. 洛谷 P5019 铺设道路

    题目描述 春春是一名道路工程师,负责铺设一条长度为 \(n\) 的道路. 铺设道路的主要工作是填平下陷的地表.整段道路可以看作是 \(n\) 块首尾相连的区域,一开始,第 \(i\) 块区域下陷的深度 ...

  10. P4233 射命丸文的笔记

    思路 题目要求求的是哈密顿回路的期望数量,实际上就是哈密顿回路的总数/有哈密顿回路的竞赛图的数量 n个点的所有竞赛图中哈密顿回路的总数为 \[ (n-1)! 2^{\frac{n(n-1)}{2}-n ...