Java进阶-ArrayList中漏删的情况

ArrayList中漏删的情况
问题描述
需求描述:
	现需要将ArrayList中存放的所有以“陈”开头的元素删除
原始ArrayList:
	list = [陈奕迅, 陈嘉桦, 陈粒, 五月天, 苏打绿, Oasis, 王菲]
目标ArrayList:
	list = [五月天, 苏打绿, Oasis, 王菲] 
	
    最快能想到的做法:
    1.遍历list(不能使用增强for以及Iterator,因为会对集合中的元素进行增删改操作,使用了便会报ConcurrentModificationException:并发修改异常),取元素
    2.判断该元素是否以“陈”开头的元素
    	是:删除
    	否:不进行操作
    	
    	相应代码:
    	for (int i = 0; i < list.size(); i++) {
            String name = list.get(i);
            if (name.startsWith("陈")){
                list.remove(i);
            }
        }
        

	但是打印输出,发现实际上的结果:list = [陈嘉桦, 五月天, 苏打绿, Oasis, 王菲],出现了漏删的情况
原因分析
产生漏删的原因:
          1.i=0"陈奕迅".startsWith("陈")remove("陈奕迅")
          2.原来索引为1"陈嘉桦"此时索引会变为0,原来索引为2"陈粒"此时索引会变为1...(删除元素之后的所有元素索引在原有索引的基础上都减去1)
          而此时i=1,因此就跳过了对"陈嘉桦"的判断,也就没有删除"陈嘉桦",删除了"陈粒"
解决办法
解决办法1:
	仍然使用正序遍历的前提下,在if方法体内加一个i--,使其不会漏掉索引为0的元素的姓名开头的判断

		for (int i = 0; i < list.size(); i++) {
            String name = list.get(i);
            if (name.startsWith("陈")){
                list.remove(i);
                i--;
            }
        }
        System.out.println("list = " + list);//打印输出 list = [五月天, 苏打绿, Oasis, 王菲]
        

解决办法2:
	倒序遍历(因为倒序遍历,修改索引的部分是已经判断过的元素,所以不会出现漏删的情况)
    	for (int i = list.size() - 1; i >= 0; i--) {
            String name = list.get(i);
            if (name.startsWith("陈")){
                list.remove(i);
            }
        }
        System.out.println("list = " + list);//打印输出 list = [五月天, 苏打绿, Oasis, 王菲]

代码实现
package com.tan.arraylist;

import java.util.ArrayList;

/*
    在ArrayList中删除元素时,需要注意可能会发生漏删的情况
 */
public class ArrayListDemo {
    public static void main(String[] args) {
//        新建ArrayList
        ArrayList<String> list = new ArrayList<>();
        
//        添加元素
        list.add("陈奕迅");
        list.add("陈嘉桦");
        list.add("陈粒");
        list.add("五月天");
        list.add("苏打绿");
        list.add("Oasis");
        list.add("王菲");
        System.out.println("list = " + list);//打印输出 list = [陈奕迅, 陈嘉桦, 陈粒, 五月天, 苏打绿, Oasis, 王菲]

//        删除所有姓陈的名字,因为需要对list进行增删改的操作,只能使用普通for或者转数组或者ListIterator进而去遍历list
        for (int i = 0; i < list.size(); i++) {
            String name = list.get(i);
            if (name.startsWith("陈")){
                list.remove(i);
            }
        }
//        我们想看到的结果:list = [五月天, 苏打绿, Oasis, 王菲]  实际上的结果:list = [陈嘉桦, 五月天, 苏打绿, Oasis, 王菲]
/*
          产生漏删的原因:
          1.i=0, "陈奕迅".startsWith("陈"),remove("陈奕迅")
          2.原来索引为1的"陈嘉桦"此时索引会变为0,原来索引为2的"陈粒"此时索引会变为1...(删除元素之后的所有元素索引都-1)
          而此时i=1,因此就跳过了对"陈嘉桦"的判断,也就没有删除"陈嘉桦",删除了"陈粒"
 */
        System.out.println("list = " + list);//打印输出


//        解决办法1:在if方法体内加一个i--,使其不会漏掉索引为0的元素的姓名开头的判断
        for (int i = 0; i < list.size(); i++) {
            String name = list.get(i);
            if (name.startsWith("陈")){
                list.remove(i);
                i--;
            }
        }
        System.out.println("list = " + list);//打印输出 list = [五月天, 苏打绿, Oasis, 王菲]

//        解决办法2:倒序遍历(因为倒序遍历,修改索引的部分是已经判断过的元素,所以不会出现漏删的情况)
        for (int i = list.size() - 1; i >= 0; i--) {
            String name = list.get(i);
            if (name.startsWith("陈")){
                list.remove(i);
            }
        }
        System.out.println("list = " + list);//打印输出 list = [五月天, 苏打绿, Oasis, 王菲]
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值