月薪15k的小党挂在了list.remove()上

640?wx_fmt=gif

做一个积极的人

编码、改bug、提升自己

我有一个乐园,面向编程,春暖花开!


640?wx_fmt=jpeg

图片来源:pixabay.com


640?wx_fmt=pngjava4all原创,欢迎关注

640?wx_fmt=gif

摘要:基友小党去面试,挂在了list.remove()上。这是一个见过就再也不会忘记的面试题,没见过的话,多半会挂掉。

640?wx_fmt=gif

面试官:在一个集合中,有几个随机字符串,有些含有a,有些没有a,用普通for循环遍历,移除含有a字符的字符串,示例如下,请问最终的打印输出结果是?

public static void main(String[] args) {	
    //建立一个list集合,里面有5个元素含有“a”,3个不含有“a”	
    List<String> list = new ArrayList<>();	
    list.add("abc");	
    list.add("anc");	
    list.add("amg");	
    list.add("agf");	
    list.add("omg");	
    list.add("aig");	
    list.add("gme");	
    list.add("wbe");	
    //遍历集合,移除含有“a”的元素	
    for(int i = 0; i < list.size();i++){	
      String str = list.get(i);	
      if(str.contains("a")){	
        list.remove(i);	
      }	
    }	
    //打印,看结果	
    for (Object st : list) {	
      System.out.print(st+"   ");	
    }	
}

小党:打印结果为:

omg   gme   wbe 

面试官:为什么?怎么分析的?

小党:遍历的过程中,含有a字符的字符串都移除了,剩下的都是没有a字符串的。

面试官:再想想。

小党:。。。。。。

面试官:今天先到这里,回去等通知吧。(这都不会,滚犊子吧)


这个问题,遇到过的人,分分钟分析出结果,但是如果,你恰巧没遇到过,也没自己想过这个问题,那很可能会卡死在这里,因为初学者或者没碰到过的开发者,压根没想过这个list.remove()这个简单方法有任何问题。

实际结果为:

anc   agf   omg   gme   wbe 

我们发现,结果中,竟然有两个字符串中含有a,它不是应该已经被移除了吗?为什么会这样呢?

重点来了!

在list集合遍历的时候,每一次循环,指针都会向后移动一位(理解为i从0开始,每次都会后移一位),但是,如果有元素被删除了,那后面的所有元素都会顺次向前移动一位(0索引的元素没了,那后面的就会补过来啊),所以每次操作结果如下表:

640?wx_fmt=png

指针一直在向后跑,当有元素移除,后面的集体前移时,就恰好会有漏网之鱼,指针没有指向过它,图上红色的,就漏掉了

那么,这个问题,怎么处理呢?

很简单,当有元素被移除时,我们把指针前移一位,弥补一下这个偏差,就不会有漏掉的了,代码如下,仅仅就是加了一句: i--;

//遍历集合,移除含有“a”的元素	
    for(int i = 0; i < list.size();i++){	
      String str = list.get(i);	
      if(str.contains("a")){	
        list.remove(i);	
        i--;	
      }	
    }

此时,再看一下指针移动和每次操作的过程:

640?wx_fmt=png

由于每次有元素被删除时,强行把指针回退一位,那么漏网之鱼就会被指针扫过,判断有a,直接移除。

注意i--的位置,当没有移除元素时,指针是没有强制回退的

此时,执行代码,结果为:

omg   gme   wbe   

此问题,还可以有第二种方法处理,倒着遍历:

关键部分代码如下:

for(int j = list.size()-1;j >= 0;j-- ){	
      String str = (String)list.get(j);	
      if(str.contains("a")){	
        list.remove(j);	
      }	
 }   

这样也可以避免这个问题。

希望你看到这篇文章后,再也不要在这个小问题上卡住。

640?wx_fmt=png     

谢谢你的阅读,祝你有所收获,也愿你每天开心愉快!

如果觉得本文对你有所帮助,欢迎转发,您的转发,就是对我最大的鼓励


文章推荐


共勉:作为一名程序员你应该怎么提一个高质量的问题?

一个二线城市程序员-周末一天的生活

五分钟能掌握UML类图中最常用到的元素

【教程】使用gitee搭建免费的图床

 五分钟学会Spring中定时器的使用


640?wx_fmt=jpeg

Java相关技术

高效软件工具

干货技术资源

前沿技术分享

FOLLOW US


你点的每个在看,我都当成了喜欢!

640?wx_fmt=gif

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REaDME.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 、资源1项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值