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. wpf treeview 数据绑定 递归绑定节点

    1.先上效果 将所有节点加入ComboBox数据源,在ComboBox中选择时下方Treeview显示该节点下的子节点. 1.xaml文件,将以下代码加入界面合适位置 <StackPanel&g ...

  2. 关于Win10安装vs2013简体中文语言包无法安装的问题

    Win10下安装VS2013后无法安装VS2013中文简体语言包,提示Windows程序兼容模式已打开. 解决方案: 1,随便找个文件夹将简体中文语言包放入其中,发送快捷方式到桌面,右击快捷方式 选择 ...

  3. js let

    <script> var a; // 变量提升 js中的作用域只有在函数中 {} 才称为作用域 if/for循环都不是 都会产生变量提升 console.log(a); { a = 2; ...

  4. python源码为何都是pass

    最近看Python代码  按照一个函数递进的看下去,最后发现,遇到很多源码什么逻辑都没写,仅仅以一个pass  结尾          但却能得到应该得到的结果,这点真的很奇怪,上网查找后 觉得下面的 ...

  5. Vue-Router路由Vue-CLI脚手架和模块化开发 之 vue-router路由

    vue-router路由:Vue.js官网推出的路由管理器,方便的构建单页应用: 单页应用(SPA)只有一个web页面的应用,用户与应用交互时,动态更新该页面的内容:简单来说,根据不同的url与数据, ...

  6. 施密特正交化 GramSchmidt

    施密特正交化 GramSchmidt 施密特正交化的原名是 Gram–Schmidt process,是由Gram和schmidt两个人一起发明的,但是后来因为施密特名气更大,所以该方法被简记为施密特 ...

  7. phtyon

    https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014316399410395 ...

  8. 【codeforces 438D】The Child and Sequence

    [原题题面]传送门 [大致题意] 给定一个长度为n的非负整数序列a,你需要支持以下操作: 1:给定l,r,输出a[l]+a[l+1]+…+a[r]. 2:给定l,r,x,将a[l],a[l+1],…, ...

  9. ZOJ 2112 Dynamic Rankings(树状数组套主席树 可修改区间第k小)题解

    题意:求区间第k小,节点可修改 思路:如果直接用静态第k小去做,显然我更改一个节点后,后面的树都要改,这个复杂度太高.那么我们想到树状数组思路,树状数组是求前缀和,那么我们可以用树状数组套主席树,求出 ...

  10. Date日期类型的绑定

    自定义类型的绑定 springmvc没有提供默认的对日期类型的绑定,需要自定义日期类型的绑定 第一张图是po类中日期属性,第二张图是页面中日期属性的内容,第三张图片是访问出现400错误 因为日期的格式 ...