这里主要谈下Java集合在使用中容易被忽略、又容易出现的两个“坑”,一个是集合与数组互相转换,另一个是集合遍历删除。主要通过代码演示。

  一.集合与数组互相转换中的“坑”  

//Test1.java
package com.itszt.test0419;import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/*** 集合与数组互相转换,含list集合元素反序排列*/
public class Test1 {public static void main(String[] args) {//一个集合对象ArrayList<String> list=new ArrayList<>();list.add("a");list.add("b");list.add("c");list.add("d");list.add("e");//集合元素正反序转换System.out.println("正序---list = " + list.toString());Collections.reverse(list);System.out.println("反序---list = " + list.toString());Collections.reverse(list);System.out.println("恢复初始状态---list"+list);//(1)集合转数组Object[] listArray1 = list.toArray();//方法1System.out.println("方法1---listArray1 = " + Arrays.toString(listArray1));String[] listArray2 = list.toArray(new String[list.size()]);//方法2System.out.println("方法2---listArray2 = " + Arrays.toString(listArray2));String[] listArray3=new String[list.size()];//方法3for(int i=0;i<list.size();i++){listArray3[i]=list.get(i);}System.out.println("方法3---listArray3 = " + Arrays.toString(listArray3));//(2)数组转集合List<Object> asList = Arrays.asList(listArray1);/*此时返回的ArrayList是Arrays的一个私有静态内部类,可以遍历查询,但是不可以像普通集合那样增删元素*/System.out.println("asList = " + asList.toString());/*asList.add("f");asList.remove("a");//若增删元素,均会抛出异常 java.lang.UnsupportedOperationException*///下述方法成功地将数组转化为集合ArrayList arrayList = new ArrayList<>(asList);arrayList.add("f");arrayList.remove("a");System.out.println("arrayList = " + arrayList.toString());}
}

  二.集合遍历删除中的“坑”  

//Test2.java
package com.itszt.test0419;
import java.util.ArrayList;
import java.util.Iterator;
/*** 集合遍历删除中的坑* 推荐对JAVA集合进行遍历删除时用迭代器*/
public class Test2 {public static void main(String[] args) {//一个集合对象ArrayList<String> list=new ArrayList<>();list.add("a");list.add("b");list.add("c");list.add("d");list.add("e");//下面是错误的遍历删除方式,抛出异常:java.util.ConcurrentModificationException/*for(String s:list){list.remove(s);}*///其实,上述代码在执行时,会转换成迭代器执行,但删除操作却用了错误的方法,如下所示:/*for(Iterator<String> it=list.iterator();it.hasNext();){String next = it.next();list.remove(next);}*///若将上述代码予以改写,就可以正常执行:/*for(Iterator<String> it=list.iterator();it.hasNext();){it.remove();}System.out.println("list = " + list.size());*//*另外,下述方式不会报异常,但只能遍历删除部分元素。这是因为:该方法中有一个严重的错误。当一个元素被删除时,列表的大小缩小并且下标变化,所以当你想要在一个循环中用下标删除多个元素的时候,它并不会正常生效。*//*for(int i=0;i<list.size();i++){list.remove(i);}System.out.println("list = " +list.size()+"---"+list.toString());*///下述方法可以清空集合内的所有元素/*list.clear();System.out.println("list = " +list.size());*///下述方式可以正确地删除指定内容的元素/*for(int i=0;i<list.size();i++){if("a".equals(list.get(i))){list.remove(i);}}System.out.println("list = " + list.toString());*//*** 那么,为什么List集合使用迭代后,就不能再用集合自身的删除方法list.remove(i)了呢?* 这是因为,ArrayList与Iterator混合使用时会导致各自的状态出现不一样,最终出现异常。* ArrayList采用size属性来维护自已的状态,而Iterator采用cursor来来维护自已的状态。* 当size出现变化时,cursor并不一定能够得到同步,除非这种变化是Iterator主动导致的。* Iterator.remove方法导致ArrayList列表发生变化时,会自动更新cursor来同步这一变化。* 但其他方式导致的ArrayList变化,Iterator是无法感知的。* ArrayList不会主动通知Iterator,这将有损效率。* 为了防止状态不一致可能引发的无法设想的后果,* Iterator会经常做checkForComodification检查,以防有变。* 如果有变,则以异常抛出,所以就抛出了上面的异常:* java.util.ConcurrentModificationException* 再来比较下面两种遍历删除方法:*///错误的删除方法 抛出异常:java.util.ConcurrentModificationException/*for(String s:list){if("a".equals(s)){list.remove(s);}}System.out.println("list = " + list.toString());*///正确的删除方法/*for(Iterator<String> it=list.iterator();it.hasNext();){if("a".equals(it.next())){it.remove();}}System.out.println("list = " + list.toString());*//*** 上述两种方法的不同结果是因为:*.next()必须在.remove()之前调用。* 在一个foreach循环中,编译器会使.next()在删除元素之后被调用,* 因此就会抛出ConcurrentModificationException异常。* 总之:* Iterator 支持从源集合中安全地删除对象,* 只需在 Iterator 上调用 remove() 即可。* 这样做的好处是可以避免 ConcurrentModificationException ,* 这个异常顾名思意:当打开 Iterator 迭代集合时,同时又在对集合进行修改。* 为此,在对集合迭代时删除或添加元素时,调用 Iterator 的remove() 方法是个安全的做法。*/}
}

转载于:https://www.cnblogs.com/lizhangyong/p/8884243.html

Java集合里的一些“坑”相关推荐

  1. Java如何读取mysql存入es_java循环读取mysql并存入java集合里

    import java.sql.Connection; import java.sql.DriverManager; public class DBHelper { private static fi ...

  2. 什么是Java集合?

    通俗来说,集合就是一个放数据容器,它主要包括collection和map集合 首先让我们来说说collection(Java.util包)集合,它继承了iterable接口 ,接口提供了迭代器 包括l ...

  3. java输出set中的元素_老师,为什么遍历Set集合里的元素,一直都是有序的输出呢?...

    源自:4-11 学生选课---通过 Set 集合管理课程 老师,为什么遍历Set集合里的元素,一直都是有序的输出呢? package com.imooc.collection; import java ...

  4. 容器(一)剖析面试最常见问题之 Java 集合框架

    转载自https://github.com/Snailclimb/JavaGuide/blob/master/docs/java/collection/Java%E9%9B%86%E5%90%88%E ...

  5. java list有序还是无序_牛批!2w字的Java集合框架面试题精华集(2020最新版),赶紧收藏。...

    一个多月前,作者和一些小伙伴决定做一系列的 Java 知识点常见重要问题的小册,方便用来夯实基础!小册的标准就一个,那就是:取精华,取重点.每一本小册,我们都会充分关注我们所总结的知识点是否达到这个标 ...

  6. Java - Java集合中的快速失败Fail Fast 机制

    文章目录 什么是 fail-fast 源码解读 Itr 为什么对集合的结构进行修改会发生并发修改异常-源码分析 修改方法之 remove 修改方法之 add 案例分享 [案例一] [案例二] [案例三 ...

  7. Java 集合框架,看这篇真的够了!

    话不多说,直接上图: Java 集合,也称作容器,主要是由两大接口 (Interface) 派生出来的: Collection 和 Map 顾名思义,容器就是用来存放数据的. 那么这两大接口的不同之处 ...

  8. Java 集合框架看这一篇就够了

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:都说了多少遍,不要再学 JSP 了!个人原创100W+访问量博客:点击前往,查看更多 话不多说,直接上图: Ja ...

  9. java map按照value排序_基础:Java集合需要注意的 5 个问题

    点击上方 Java后端,选择 设为星标 优质文章,及时送达 Java集合中的List.Set和Map作为Java集合食物链的顶级,可谓是各有千秋.本文将对于List.Set和Map之间的联系与区别进行 ...

  10. 2020面试准备之Java集合

    文章目录 1.Java集合类框架的基本接口有哪些? 2.Collection 和 Collections 有什么区别? 3.为什么集合类接口没有实现 Cloneable 和 Serializable ...

最新文章

  1. 11、修改和删除索引(DROP INDEX)
  2. 通过游戏的方式与陌生人聊天,破冰是如何做到的?
  3. 基于jquery的上传插件Uploadify 3.1.1在MVC3中的使用
  4. 流浪不是我的初衷 ... ...
  5. 图像正确(相当于这个小项目就要结尾了)
  6. ai皮肤检测分数_德国猫咪皮肤检测仪,为什么这么火?| 云美来
  7. Anaconda+tensorflow+keras的下载与安装
  8. 在没有导师的指导下,研究生如何阅读文献、提出创见、写出论文?
  9. 计算机专硕报考专业代码,什么是报考专业代码 考研专业代码到底是什么意思...
  10. 如何持续突破性能表现? | DX研发模式
  11. cad计算机绘图知识点,学习Auto CAD制图需要掌握哪些重要的知识点?
  12. 中控指纹仪linux驱动下载,中控zk4500指纹采集器驱动下载_中控zk4500指纹采集器驱动官方下载-太平洋下载中心...
  13. 对比阿里云服务器和腾讯云服务器两者的不同之处
  14. TYPEC-CC逻辑芯片-E-MARK数据线-浅析
  15. js获取浏览器高度和宽度值(多浏览器)
  16. 腾讯文智自然语言处理介绍与情感分析API调用
  17. 删除cookie删不掉的问题
  18. git 冲突解决一把梭
  19. java 泛型方法 实例化_Java让泛型实例化的方法
  20. 查询亿级数据毫秒级返回!Elasticsearch 是如何做到的?

热门文章

  1. asp.net 获取IP地理位置的几个主要接口
  2. .NET2.0 事务处理
  3. AjaxControlToolKit之AutoCompleteExtender用法
  4. 本地图片预览代码(支持 IE6、IE7)
  5. ICLR 2022 论文列表公布,接收率高达 32%
  6. 【预训练模型】预训练语言模型的前世今生之风起云涌
  7. 【Linux】shell命令总结
  8. 西瓜书读书笔记5-决策树的分裂原则
  9. matplotlib无法显示图片的解决方法(non-gui backend)
  10. 数值优化(二):信赖域方法与二维空间法