工程开发之集合规约

一、Map类型的案例、源码解析与规约

首先,来看下面一段代码;思考下这个方法会有什么问题?

工程开发之集合规约

       有些查询结果会报java.lang.IllegalStateException,这是为什么呢?根据报错,定位并剖析Collectors.toMap方法内部构造:

 

工程开发之集合规约

这里引出一个集合规约:

【强制】在使用java.util.stream.Collectors类的toMap()方法转为Map集合时,一定要使用含有参数类型为BinaryOperator,参数名为mergeFunction的方法,否则当出现相同key值时会抛出IllegalStateException异常

       按照规约,加上参数类型为BinaryOperator,参数名为mergeFunction的方法,如下图所示:

工程开发之集合规约

然而,再次测试运行,会抛出空指针异常。因此,需要再次从源码入手,一行一行地追根究底:

工程开发之集合规约

显然根据堆栈信息,NPE是藏在HashMap地merge方法中地,点进去继续看:

工程开发之集合规约

 

一行一行地找,先看map的merge方法:

工程开发之集合规约

二、List类型的源码解析与规约

首先,给出一个结论:ArrayList的subList结果不可强转成ArrayList;然后看如下源码:

工程开发之集合规约

注释的第一句话就解释清楚了,内部类SubList,并不是ArrayList本身,而是ArrayList的一个视图;对于SubList的所有操作最终会反映到原列表上。

工程开发之集合规约

 

工程开发之集合规约

       SubList的所有操作最终会反映到原列表上,因此ArrayList的subList()返回的是ArrayList的内部类SubList,强转成ArrayList,则会抛出ClassCastException异常。

在subList场景中,需要注意:

  1. 高度注意对父集合元素的增加或删除,均会导致子列表的遍历;
  2. 增加、删除产生ConcurrentModificationException;
  3. 每次sublist子列表的遍历、增加、删除都会调用checkForComodification()。

工程开发之集合规约

扩展

集合Collection与Set、List、Map、Queue的关系图

工程开发之集合规约

上图中红色为接口蓝色为抽象类绿色为并发包中的类灰色为早期线程安全的类

上一篇:真实有效户口本怎么办


下一篇:从问题入手,深入了解JavaScript中原型与原型链