Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >使用List中的remove方法遇到的坑,不信你没有踩过!

使用List中的remove方法遇到的坑,不信你没有踩过!

作者头像
后端码匠
发布于 2020-07-21 06:38:27
发布于 2020-07-21 06:38:27
1.9K00
代码可运行
举报
文章被收录于专栏:后端码匠后端码匠
运行总次数:0
代码可运行

blog.csdn.net/Alice_qixin/article/details/80256882

先来看一下下面的样例是否符合你的问题场景

list中根据判断条件符合的就remove掉一个数据

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 public static void main(String[] args) {
        List<CaseHead> list=new ArrayList<CaseHead>();
        CaseHead caseHead1=new CaseHead();
        caseHead1.setCaseid(a);
        CaseHead caseHead2=new CaseHead();
        caseHead2.setCaseid(b);
        CaseHead caseHead3=new CaseHead();
        caseHead3.setCaseid(c);
        CaseHead caseHead4=new CaseHead();
        caseHead4.setCaseid(d);
        CaseHead caseHead5=new CaseHead();
        caseHead5.setCaseid(e);
        list.add(caseHead1);
        list.add(caseHead2);
        list.add(caseHead3);
        list.add(caseHead4);
        list.add(caseHead5);


        List<String> list2=new ArrayList<String>();
        list2.add(a);
        list2.add(b);

        for (int i = 0; i < list.size(); i++) {
            String caseid=list.get(i).getCaseid();
            for (int j = 0; j <list2.size() ; j++) {
                String l=list2.get(j);
                if (caseid.equals(l)){
                    list.remove(i);
                }
            }


        }

        for (int a = 0; a < list.size(); a++) {
            System.out.println(list.get(a).getCaseid());
        }}

结果是什么?

结果是一下。根据以上代码,希望得到的结果是 cde 但是运行结果是bcde那么问题来了为什么会得到一下结果呢

先看一下list remove的源码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 删除ArrayList指定位置的元素
    public E remove(int index) {
        RangeCheck(index);//检查index是否超出list大小范围,否则抛出异常
        modCount++;
        E oldValue = (E) elementData[index];//elementData是实现list的数组
        int numMoved = size - index - 1;//当执行删除操作是后面的元素全部向前面移动一位
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                 numMoved);
        elementData[--size] = null;
        return oldValue;
    }
    // 删除ArrayList的指定元素
    public boolean remove(Object o) {
        if (o == null) {
          for (int index = 0; index < size; index++)
             if (elementData[index] == null) {
                 fastRemove(index);
                return true;
            }
        } else {
            for (int index = 0; index < size; index++)
              if (o.equals(elementData[index])) {
                  fastRemove(index);
                  return true;
              }
        }
        return false;
   }
  //快速删除第index个元素
  private void fastRemove(int index) {
        modCount++;  
        int numMoved = size - index - 1;  
        if (numMoved > 0)  
            System.arraycopy(elementData, index+1, elementData, index,  
                             numMoved);  
        elementData[--size] = null; 
   } 

源码可知,List在删除指定位置的对象时,执行删除操作是后面的元素全部向前面移动一位

因为,当你remove掉一个对象时,list的就少了一个 index 0的被remove了,之前index 1的数据就自动变为index 0了。arrayList是有顺序数组,从0开始。如果从前开始删除实际上就相当于跳着删除了。

解决办法1:

每次删除之后i--自动返回到上一个index开始

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    public static void main(String[] args) {
        List<CaseHead> list=new ArrayList<CaseHead>();
        CaseHead caseHead1=new CaseHead();
        caseHead1.setCaseid(a);
        CaseHead caseHead2=new CaseHead();
        caseHead2.setCaseid(b);
        CaseHead caseHead3=new CaseHead();
        caseHead3.setCaseid(c);
        CaseHead caseHead4=new CaseHead();
        caseHead4.setCaseid(d);
        CaseHead caseHead5=new CaseHead();
        caseHead5.setCaseid(e);
        list.add(caseHead1);
        list.add(caseHead2);
        list.add(caseHead3);
        list.add(caseHead4);
        list.add(caseHead5);


        List<String> list2=new ArrayList<String>();
        list2.add(a);
        list2.add(b);

        for (int i = 0; i < list.size(); i++) {
            String caseid=list.get(i).getCaseid();
            for (int j = 0; j <list2.size() ; j++) {
                String l=list2.get(j);
                if (caseid.equals(l)){
                    list.remove(i);
                    i--;
                }
            }


        }

        for (int a = 0; a < list.size(); a++) {
            System.out.println(list.get(a).getCaseid());
        }
}

第二种解决方法

倒着删除从后往前遍历删除,从index大的往index小的删

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    public static void main(String[] args) {
        List<CaseHead> list=new ArrayList<CaseHead>();
        CaseHead caseHead1=new CaseHead();
        caseHead1.setCaseid(a);
        CaseHead caseHead2=new CaseHead();
        caseHead2.setCaseid(b);
        CaseHead caseHead3=new CaseHead();
        caseHead3.setCaseid(c);
        CaseHead caseHead4=new CaseHead();
        caseHead4.setCaseid(d);
        CaseHead caseHead5=new CaseHead();
        caseHead5.setCaseid(e);
        list.add(caseHead1);
        list.add(caseHead2);
        list.add(caseHead3);
        list.add(caseHead4);
        list.add(caseHead5);


        List<String> list2=new ArrayList<String>();
        list2.add(a);
        list2.add(b);

        for (int i = list.size()-1; i >= 0; i--) {
            String caseid=list.get(i).getCaseid();
            for (int j = 0; j <list2.size() ; j++) {
                String l=list2.get(j);
                if (caseid.equals(l)){
                    list.remove(i);

                }
            }


        }

        for (int a = 0; a < list.size(); a++) {
            System.out.println(list.get(a).getCaseid());
        }
}

此问题,本人仅在remove对象时发现到此错误。当list里面是基本类型数据时并没有发生以上问题。在此记好。仅供参考

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020/07/18 20:14:59,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 后端码匠 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【数据结构】顺序表
前言: 小编在开始之前就已经发了顺序表的相关用例,想看的小伙伴可以去看看哦http://t.csdnimg.cn/saIbn
用户11288949
2024/09/24
670
【数据结构】顺序表
ArrayList的删除姿势你都知道了吗
前几天有个读者由于看了《ArrayList哪种遍历效率最好,你真的弄明白了吗?》问了个问题普通for循环ArrayList为什么不能删除连续重复的两个元素?其实这个描述是不正确的。正确的应该是普通for循环正序删除,不能删除连续的元素所以就产生了这个文章。
java金融
2020/06/23
8410
ArrayList的删除姿势你都知道了吗
ArrayList、LinkedList哪家强,据说90%人都不知道
写代码的时候很经常就会用到List集合,但是很多时候我看到童鞋们都是用ArrayList来作为实现类,很少用LinkedList,鉴于这两个集合使用频率特别高,所以老师给童靴们分析一下,他们在不同场景下面效率,谁低谁高。
林老师带你学编程
2020/07/21
2530
Java面试题之List(一)
我们都知道,Java面试中避免不了的要涉及到对各种框架和源码的盘问。有的面试官会直接点,问我们对ArrayList的源码的理解,有的会间接的提问。
黑洞代码
2021/01/14
4390
知识改变命运 数据结构【顺序表】
线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结 构,常见的线性表:顺序表、链表、栈、队列… 线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物 理上存储时,通常以数组和链式结构的形式存储。
用户11319080
2024/10/17
890
知识改变命运 数据结构【顺序表】
集合遍历中删除行不行「建议收藏」
import java.util.ArrayList; import java.util.List;
全栈程序员站长
2022/08/09
5230
Java Review - ArrayList 源码解读
为追求效率,ArrayList没有实现同步(synchronized),如果需要多个线程并发访问,用户可以手动同步,也可使用Vector替代
小小工匠
2021/11/15
2300
【Java集合-3】ArrayList简析
ArrayList是一个数组队列,相当于动态数组。与Java中的数组相比,它的容量能动态增长。
云深i不知处
2020/09/16
5280
List中remove()方法的陷阱,被坑惨了!
Java的List在删除元素时,一般会用list.remove(o)/remove(i)方法。在使用时,容易触碰陷阱,得到意想不到的结果。总结以往经验,记录下来与大家分享。
好好学java
2021/10/09
6480
list.remove()时出问题,集合的remove方法注意事项1
集合有一个方法叫remove(index),这是用来移除集合元素的,但是使用的时候,会有一个问题,很多人不注意这个问题,会发现使用完这个方法后,数据对不上了。看下面的小案例:
IT云清
2019/01/22
1.1K0
顺序表的奥秘:高效数据存储与检索
小舒不服输
2024/01/31
1470
顺序表的奥秘:高效数据存储与检索
ArrayList与CopyOnWriteArrayList常见操作与问题
在工作和学习中,经常碰到删除ArrayList里面的某个元素,看似一个很简单的问题,却很容易出bug。不妨把这个问题当做一道面试题目,我想一定能难道不少的人。今天就给大家说一下在ArrayList循环遍历并删除元素的问题。首先请看下面的例子:
chengcheng222e
2021/11/04
8110
jdk源码分析之List--使用中的坑
之前讲解了一篇 jdk源码分析之List--常用实现类分析与对比,讲述了常用List实现类以及使用方式和性能对比,那么此篇文章针对List使用过程中遇到的一些坑做一些总结和分析。
叔牙
2020/11/19
4470
jdk源码分析之List--使用中的坑
Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例
概要 上一章,我们学习了Collection的架构。这一章开始,我们对Collection的具体实现类进行讲解;首先,讲解List,而List中ArrayList又最为常用。因此,本章我们讲解ArrayList。先对ArrayList有个整体认识,再学习它的源码,最后再通过例子来学习如何使用它。内容包括: 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3308556.html 第1部分 ArrayList介绍 ArrayList简介 ArrayList 是一个数
老白
2018/03/19
9980
Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例
提高Java编程效率:ArrayList类的使用技巧
今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。
喵手
2023/11/24
2370
提高Java编程效率:ArrayList类的使用技巧
JDK1.8源码(五)——java.util.ArrayList 类
  关于 JDK 的集合类的整体介绍可以看这张图,本篇博客我们不系统的介绍整个集合的构造,重点是介绍 ArrayList 类是如何实现的。 1、ArrayList 定义 ArrayList 是一个用
IT可乐
2018/03/30
1.1K0
JDK1.8源码(五)——java.util.ArrayList 类
Java集合遍历时遇到的坑
面试题中可能会被问到对Java集合的了解情况,并深入集合底层的源码,以及使用集合的时候有没有遇到坑——这时候其实是想考察大家在日常工作中是否细心,一般不建议说,没有遇到坑,因为这样会给面试官感觉大家在工作中不细心,不仔细。
黑洞代码
2021/01/14
6370
Java集合遍历时遇到的坑
遍历数据时arraylist效率高于linkedlist_遍历问题种类
一个 java 程序猿比较广为人知的小知识 ,是 ArrayList 和 LinkedList 最好使用迭代器删除,而不是遍历删除。
全栈程序员站长
2022/09/23
7170
遍历数据时arraylist效率高于linkedlist_遍历问题种类
在ArrayList的循环中删除元素,会不会出现问题?
在 ArrayList 的循环中删除元素,会不会出现问题?我开始觉得应该会有什么问题吧,但是不知道问题会在哪里。在经历了一番测试和查阅之后,发现这个“小”问题并不简单!
Wizey
2018/09/29
3.2K0
在ArrayList的循环中删除元素,会不会出现问题?
ArrayList 分析以及相关方法介绍
java.util.ArrayList 是我们最常用的一个类,ArrayList 底层是动态数组,读者可以把它理解为数组的实现
cxuan
2019/06/03
5170
相关推荐
【数据结构】顺序表
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档