首页 > 其他分享 >阿里巴巴为什么这样强制从List中删除元素

阿里巴巴为什么这样强制从List中删除元素

时间:2023-04-04 11:57:53浏览次数:48  
标签:阿里巴巴 删除 List list remove 冥王星 item

阿里巴巴为什么这样强制从List中删除元素

 

还是先举个例子,你侄女对天文知识感兴趣,然后你就用程序写了太阳系九大星系(水星、金星、地球、火星、木星、土星、天王星、海王星、冥王星)的运行轨迹图,然后拿给侄女看。然后她说错了错了,你的知识太旧了,多了一颗星。根据2006年8月24日国际天文联合大会召开,在会议上经过投票表决,冥王星被降级为矮行星,太阳系目前只剩下八颗行星。所以你需要删除一颗星。这个时候你打开电脑开始删除冥王星。

你从下面List中删除一颗星。

List<String> tempList = Arrays.asList("水星","金星","地球","火星",
"木星","土星","天王星","海王星","冥王星","冥王星");

怎么删除List中的冥王星呢?[PS为了演示某些删除方法不可靠,重复写了冥王星] 。

先写一段阿里规约:

【强制】不要再foreach循环里进行元素的remove/add操作,remove元素请使用Iterator方式,如果并发的操作,需要对Iterator对象加锁。

好了,那就让我们来写所有可能删除元素的方法

1:普通的for循环的删除(不可靠)。

复制代码
List<String> list = new ArrayList(tempList);
         for (int i = 0; i < list.size(); i++) {
            String str = list.get(i);
            if ("冥王星".equals(str)) {
                list.remove(i);
            }
        }
        System.out.println(list);
复制代码

运行结果如下:

[水星, 金星, 地球, 火星, 木星, 土星, 天王星,    海王星, 冥王星]

奇了怪了,没删除干净?

问题出在 list.size(),因为 list.size() 和 i 都是动态变化的,i 的值一直在累加,list.size() 一直在减少,所以 list 就会早早结束了循环。所以这种方式虽然不会报错,但存在隐患,并且不容易被察觉,不建议使用。

2:普通的for循环提取变量进行删除(这个更不可靠,会报错)。

复制代码
List<String> list = new ArrayList(tempList);
        int size = list.size();
        for (int i = 0; i < size; i++) {
            String result = list.get(i);
            if ("冥王星".equals(result)) {
                list.remove(i);
            }
        }
        System.out.println(list);
复制代码

结果如下:

这更不对了,一下子搞出个下标越界。

因为 size 变量是固定的,但 list 的实际大小是不断减小的,而 i 的大小是不断累加的,一旦 i >= list 的实际大小肯定就异常了。

3:普通的for循环倒叙删除(这个用法可以)。

复制代码
for (int i = list.size() - 1; i > 0; i--) {
            String result = list.get(i);
            if ("冥王星".equals(result)) {
                list.remove(i);
            }
        }
        System.out.println(list);
复制代码

运行结果如下:

[水星, 金星, 地球, 火星, 木星, 土星, 天王星, 海王星]

4:使用增强的for循环删除(会抛出异常,不推荐,注意我这次为了演示效果,把行星的顺序换一下),不少开发者喜欢用这种方式。

复制代码
List<String> tempList = Arrays.asList("水星","金星","地球","火星",
"冥王星","土星","天王星","海王星","冥王星","木星");
         List<String> list = new ArrayList(tempList);
        for (String item : list) {
            if ("冥王星".equals(item)) {
                list.remove(item);
            }
        }
        System.out.println(list);
复制代码

结果如下:

奇了怪了,又抛异常了。不过这次的异常和上面的下标异常不太一样,这次是:

java.util.ConcurrentModificationException

这个是集合操作中很常见的异常之一,即并发修改异常!

增强的 for循环,其内部是调用的 Iterator 的方法,取下个元素的时候都会去判断要修改的数量(modCount)和期待修改的数量(expectedModCount)是否一致,不一致则会报错,而 ArrayList 中的 remove 方法并没有同步期待修改的数量(expectedModCount)值,所以会抛异常了。

5、迭代器循环迭代器删除(可靠,也是十分推荐的用法)。

复制代码
Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()){
            String item = iterator.next() ;
            if ("冥王星".equals(item)){
                iterator.remove();
            }
        }
        System.out.println(list);
复制代码

结果如下,十分完美和正确:

[水星, 金星, 地球, 火星, 土星, 天王星, 海王星, 木星]

这是因为迭代器中的 remove 方法将期待修改的数量(expectedModCount)值进行了同步。

 

6:迭代器循环集合删除(这个可能很多开发者也会这样写,也可能会抛出异常的)。

复制代码
Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()){
            String item = iterator.next() ;
            if ("冥王星".equals(item)){
                list.remove(item);
            }
        }
        System.out.println(list);
复制代码

结果如下:

7:Stream filter 过滤(十分推荐,当然使用这个删除需要JDK的环境在8及其8以上的版本)。

list = list.stream().filter(item -> !"冥王星".equals(item)).
 collect(Collectors.toList());
 System.out.println(list);

结果如下,十分完美和正确:

这个方法利用了 Stream 的筛选功能,快速过滤所需要的元素,虽然不是进行集合删除,但达到了同样的目的,这种方法要更简洁

看了上面的几个例子,相信你熟悉了List删除元素的用法了,希望你看了上面的例子,开发的时候不会再犯错了。

 

标签:阿里巴巴,删除,List,list,remove,冥王星,item
From: https://www.cnblogs.com/sexintercourse/p/17285923.html

相关文章

  • java lambda List 查找 anyMatch() allMatch() noneMatch()
    packagelambda.list;importcn.hutool.core.util.ObjectUtil;importlombok.extern.slf4j.Slf4j;importorg.junit.Test;importpojo.Dome;importjava.util.ArrayList;importjava.util.List;/***@Author:xxx*@date2021/5/14**/@Slf4jpublicclassSe......
  • java lambda List 分组 Collectors.groupingBy
    packagelambda.list;importlombok.extern.slf4j.Slf4j;importorg.junit.Test;importpojo.Dome;importjava.util.ArrayList;importjava.util.List;importjava.util.Map;importjava.util.stream.Collectors;/***@Author:xxx*@date2021/5/14**/@Sl......
  • c# list删除元素
    新建一个集合:删除其中一个元素List<String>tempList=newList<string>{"水星","金星","地球","火星","木星","土星","天王星","海王星","冥王星","冥王星"};tempList.Remove("冥王星&qu......
  • Mac - 查找并删除大文件(其他项占用过多解决方案)
    Mac存储空间中「其他」项占用非常大,通过工具来查看文件并清除大文件。工具名称:OmniDiskSweeper官网下载地址OSX里面的Other就是所有其他的文件。所有的文档,包括.pdf.doc.psd所有的压缩文件和磁盘映像包括.zip.dmg.iso所有的用户数据所有的系统文件包括Sy......
  • 最长连续序列(并查集、数组)、复原 IP 地址(字符串、回溯)、删除链表的倒数第 N 个结
    最长连续序列(并查集、数组)给定一个未排序的整数数组nums,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。请你设计并实现时间复杂度为O(n)__的算法解决此问题。示例1:输入:nums=[100,4,200,1,3,2]输出:4解释:最长数字连续序列是[1,2,3,4]。它的长度为4......
  • 恢复出厂设置时删除手机上所有联系人
    修改nvram_common_config.c中相应phonebook的nv项的属性即可,将NVRAM_ATTR_FACTORY_RESET添加到对应nv项属性中。相关的NV项及说明如下:NVRAM_EF_PHB_LN_ENTRY_LID:calllog相关的信息NVRAM_EF_PHB_LID:手机中的联系人信息NVRAM_EF_PHB_GROUP_INFO_LID......
  • <Android> ListView 列表控件的使用-李国庆-专题视频课程
    ListView列表控件的使用—15573人已学习课程介绍        1,ListView介绍;2,原理讲解;3,简单实现;4,ListView扩展;课程收益    通过学习本课程,具有一定的Android开发技能和知识,熟练掌握这一专题中集成组件与布局属性、实现listview基本用法,及简单扩展。讲师介绍    ......
  • android 解决ScrollView嵌套ListView的问题,不能全屏,全屏不能显示下面控件
    在开发中遇到ScrollView嵌套ListView的问题,最开始发出不能全屏,效果是这样的;但我想要的效果是这样的:下面看一下布局文件:<?xmlversion="1.0"encoding="utf-8"?><ScrollViewxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_p......
  • List接口和常用方法
    P2List接口和常用方法一、List接口基本介绍List接口是Collection接口的子接口List集合类中元素有序(即添加顺序和取出顺序一致)、且可重复List集合类中的每一个元素都有其对应的顺序索引,即支持索引。List容器中都对应一个整数型的序号记载其在容器中的位置,可以根据序......
  • 019redis3.0集群删除节点
    1:如果删除的节点是主节点,这里我们删除192.168.2.20:7006节点,这个节点有1000个哈希槽首先要把节点中的哈希槽转移到其他节点中,执行下面的命令cd /usr/local/redis3.0/src./redis-trib.rb reshard 192.168.2.20:7000系统会提示我们要移动多少哈希槽,这里移动1000个,因为192.168.2.20......