工程开发之集合规约

一、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的关系图

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值