• ArrayList中remove()方法删除长度大于5的元素之后下标重定位的问题


    1、问题阐述


     需求描述

    有一个ArrayList数组,要求删除长度大于5的字符串,如:arr = {"ab1","123ad","bca","dadfadf","dddaaa","你好啊","我来啦","别跑啊"};

    要求结果输出

    {"ab1","123ad","bca","你好啊","我来啦","别跑啊"}

    遇到的问题

      删除元素可以用remove()方法,我开始用的是for循环来操作,先循环遍历arr集合,如果发现该元素的长度大于5就删除该元素。此时出现如下几个问题:

      问题1:假设此时删除的元素下标为3,后面的元素会自动往前移动一位,填补被删除了的元素,下一次循环遍历下标就变成了4,直接跳过了之前填补的位置,但刚刚的位置的元素已经变了,此时这个元素已经遍历不到了。

      问题2:删除了元素但arr的长度此时还是原来的长度,没有更新,结果导致数组下标溢出。

      思考之后发现使用for循环的弊端就是i++及arr.size()的问题。

      中心难点是如何能够在再一次遍历刚刚位置上的元素,弥补删除元素之后自动跳到下一个元素的漏洞。问题代码与图解如下:

    1 for (int j = 0; j < arr.size(); j++) {
    2     String str = (String) arr.get(i);
    3     if (str.length() > 5) {
    4         arr.remove(str);
    5     }
    6 }

    错误提示

    Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 6, Size: 6
    at java.util.ArrayList.rangeCheck(Unknown Source)
    at java.util.ArrayList.get(Unknown Source)

    2、解决方案


     方案1:使用迭代器,利用迭代器的remove方法删除元素,优点是不用考虑数组的长度

    Iterator it = arr.iterator();
    while (it.hasNext()) {
      String str = (String) it.next();
      if (str.length() > 5) { // 判断字符串的长度是否大于5
        it.remove(); // 使用迭代器的remove方法
      } else {
        System.out.println(str);
      }
    }

      方案2:使用迭代器,利用迭代器Iterator的子类listIterator的remove方法删除元素

    ListIterator it = (ListIterator) arr.listIterator();
    while (it.hasNext()) {
        String str = (String) it.next();
        if (str.length() > 5) {
            it.remove();
        }
    }

     3、经验总结


    ① 如果遍历集合的时候,不需要对集合中的元素进行操作(增加、删除),推荐使用增强for循环

    ② 如果遍历集合的时候,需要对集合中的元素进行操作(增加、删除),那么只能使用迭代器

    • 使用迭代器进行迭代器(Iterator)进行操作时,不允许使用集合的add、remove方法,但是可以使用迭代器的remove方法
    • Iterator还有一个子接口(ListIterator),提供了add和remove方法,可以在遍历list集合的时候,对集合进行增加删除操作。

    阅罢此文,如果您觉得本文不错并有所收获,请【打赏】或【推荐】,也可【评论】留下您的问题或建议与我交流。 你的支持是我不断创作和分享的不竭动力!

    作者:寒冰雪
    出处:https://home.cnblogs.com/u/snow1234/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在章页面明显位置给出原文链接,否则保留追究法律责任的权利。
  • 相关阅读:
    Extract Manifest File From Application (exe)
    Basis: Command and Immediate Window
    MVC框架啊
    Brian's Guide to Solving Any Perl Problem
    [bbk3106]第13集 Chapter 07 介绍oracle的asm存储设备
    ASM
    [bbk3105]第12集 Chapter 07 介绍oracle的asm存储设备
    [bbk3104]第11集 Chapter 07 介绍oracle的asm存储设备
    [bbk3103]第10集 Chapter 06 介绍RAC的体系结构
    手把手一起安装RAC
  • 原文地址:https://www.cnblogs.com/snow1234/p/7193515.html
Copyright © 2020-2023  润新知