解决JAVA遍历List集合,删除数据时出现的问题

一、问题描述

有时候,我们会遇到在遍历List集合的过程中删除数据的情况。

看着自己写的代码,感觉完全没有问题,但就是达不到预期的效果,这是为什么呢?下面我们来分析下

String str1 = new String("1");
String str2 = new String("2");
String str3 = new String("3");
String str4 = new String("4");
String str5 = new String("5");
List list = new ArrayList();
list.add(str1);
list.add(str2);
list.add(str3);
list.add(str4);
list.add(str5);
System.out.println("list.size()=" + list.size());     

for (int i = 0; i < list.size(); i++) {
    list.remove(i);
  // i--;
  //System.out.println(i+" "+list.get(i)+" ");
}
System.out.println("after remove:list.size()=" + list.size());

本来预期结果应该是:

list.size()=5 
after remove:list.size()=0

但实际上结果却是:

list.size()=5 
after remove:list.size()=2

原因如下: List每remove掉一个元素以后,后面的元素都会向前移动 ,此时如果执行i++,则刚刚移过来的元素没有被读取。

分析:

  • List中有5条数据,需要循环5次,
  • 第一次数据为:1 2 3 4 5
  • 执行完remove(0) 后,数据为 2 3 4 5  , i=1
  • 第二次数据为:2 3 4 5
  • 执行完remove(1) 后,数据为 2 4 5  , i=2
  • 第三次数据为:2 4 5
  • 执行完remove(2) 后,数据为 2 4  , i=3
  • 此时如果加上上面注释的代码 System.out.println(i+" "+list.get(i)+" "); 循环第4、5次时就会出现异常

二、解决方法

解决方法1:每移过一次后,再把 i 移回来

for (int i = 0; i < list.size(); i++) {
  list.remove(i);
  i--;
}

解决方法2:先删除后面的元素

for (int i = list.size()-1; i >= 0; i--) { list.remove(i); }

解决方法3:使用iterator删除

for(Iterator it = list.iterator();it.hasNext();){
  it.remove();
}

以上就是解决JAVA遍历List集合时,删除数据出现的问题的详细内容,更多关于JAVA遍历List集合 删除数据的资料请关注我们其它相关文章!

时间: 2020-07-13

java中List集合及其遍历详解

1. 首先List<E>集合继承与Collection<E>,是一个接口. ①  Collection (集合框架是JDK1.2版本出现的) ②   list:是有序的,元素可以重复,以为该集合体系有索引.    经常用到的是实现该接口的ArrayList和LinkedList类 ③   Arraylist:  底层的数据结构使用的是数组结构, 特点: 查询速度很快,但是增删稍慢.线程不同步 LinkedList: 底层使用的是链表数据结构. 特点: 增删速度很快,查询稍慢. Ve

java arrayList遍历的四种方法及Java中ArrayList类的用法

java arrayList遍历的四种方法及Java中ArrayList类的用法 package com.test; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class ArrayListDemo { public static void main(String args[]){ List<String> list = new ArrayList<String

Java如何在List或Map遍历过程中删除元素

遍历删除List或Map中的元素有很多种方法,当运用不当的时候就会产生问题.下面通过这篇文章来再学习学习吧. 一.List遍历过程中删除元素 使用索引下标遍历的方式 示例:删除列表中的2 public static void main(String[] args) { List<Integer> list = new ArrayList<Integer>(); list.add(1); list.add(2); list.add(2); list.add(3); list.add(

Java中List集合的遍历实例详解

 一.对List的遍历有三种方式   List<String> list = new ArrayList<String>(); list.add("testone"); list.add("testtwo"); ... 第一种: for(Iterator<String> it = list.iterator(); it.hasNext(); ) { .... } 这种方式在循环执行过程中会进行数据锁定,    性能稍差,    同

Java List集合方法及遍历过程代码解析

集合元素框架 public class ListDemo02 { public static void main(String[] args) { //创建集合对象 List<String> list = new ArrayList<String>(); //添加元素 list.add("hello"); list.add("world"); list.add("java"); //输出集合对象 System.out.pr

Java遍历集合方法分析(实现原理、算法性能、适用场合)

概述 Java语言中,提供了一套数据集合框架,其中定义了一些诸如List.Set等抽象数据类型,每个抽象数据类型的各个具体实现,底层又采用了不同的实现方式,比如ArrayList和LinkedList. 除此之外,Java对于数据集合的遍历,也提供了几种不同的方式.开发人员必须要清楚的明白每一种遍历方式的特点.适用场合.以及在不同底层实现上的表现.下面就详细分析一下这一块内容. 数据元素是怎样在内存中存放的? 数据元素在内存中,主要有2种存储方式: 1.顺序存储,Random Access(Di

Java实现一个简单的定时器代码解析

定时的功能我们在手机上见得比较多,比如定时清理垃圾,闹钟,等等.定时功能在java中主要使用的就是Timer对象,他在内部使用的就是多线程的技术. Time类主要负责完成定时计划任务的功能,就是在指定的时间的开始执行某个任务. Timer类的作用是设置计划任务,而封装任务内容的类是TimerTask类.此类是一个抽象类,继承需要实现一个run方法. 利用java制作定时器比较简单,有现成的接口帮助实现.java中制作定时器使用的是Timer和TimerTask,是util包的.java.util

java中幂指数值的运算代码解析

说到幂指数的运算我们就会用到Math.pow(doublea,doubleb),返回的结果是a的b次方. 在Java中,当我们计算2的n次方时,可以直接用Math.pow来计算.非常方便. 但是,已知一个幂的结果为M和幂的底数a,现在要求幂的指数n.Math中提供的有log(double)方法,但是只能传入一个参数,即M.那么问题来了,如何简单.方便.快捷的达到我们的要求呢?答案如下: n=Math.log(M)/Math.log(a); 这个方法可以满足我们大多数幂指数的计算,但是每次访问的值

JAVA StringBuffer类与StringTokenizer类代码解析

 StringBuffer类提供了一个字符串的可变序列,类似于String类,但它对存储的字符序列可以任意修改,使用起来比String类灵活得多.它常用的构造函数为: StringBuffer() 构造一个空StringBuffer对象,初始容量为16个字符. StringBuffer(Stringstr) 构造一个StringBuffer对象,初始内容为字符串str的拷贝. 对于StringBuffer类,除了String类中常用的像长度.字符串截取.字符串检索的方法可以使用之外,还有两个较为

java中的异或问题代码解析

java的位运算符中有一个叫异或的运算符,用符号(^)表示,其运算规则是:两个操作数的位中,相同则结果为0,不同则结果为1.下面看一个例子: public class TestXOR{ public static void main(String[] args){ int i = 15, j = 2; System.out.println("i ^ j = " + (i ^ j)); } } 运行结果是:i^j=13. 分析上面程序,i=15转成二进制是1111,j=2转成二进制是00

java springmvc 注册中央调度器代码解析

这篇文章主要介绍了java springmvc 注册中央调度器代码解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在WEB-INF下的web.xml中配置 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="htt

Java数组集合的深度复制代码实例

这篇文章主要介绍了Java数组集合的深度复制代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Java当我们想要对一个数组进行一些操作,同时又不希望对原来的数组数据有影响的时候,使用引用是不能满足我们的需求的, 这时候我们可以使用System.arraycopy()方法实现,对用这两种复制方式,我们习惯称前者为浅复制,后者为深复制.深复制的 实现方法如下: public static void arraycopyTest() { int[

Java简单数据加密方法DES实现过程解析

这篇文章主要介绍了Java简单数据加密方法DES实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.数据在网络中传输时,需要进行加密处理 双方约定一个相同的key(key不在网络中进行传输,只传输加密数据),然后根据将key根据一定的DES规则转换,得到真正的key,在进行加密和解密,为了增加安全性,加密过程中再加上编码base64转换,解密时先解码base64 加密和解密的完整的代码: package com.cmit.hall.

通过java记录数据持续变化时间代码解析

这篇文章主要介绍了通过java记录数据持续变化时间代码解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.需求:获取count为null和不为null的持续变化 [{count=0, time=0}, {count=10, time=1000}, {count=20, time=2000}, {count=30, time=3000}, {count=40, time=4000}, {count=null, time=5000}, {cou