java8stream中Collectors.toMap空指针问题及解决_第1页
java8stream中Collectors.toMap空指针问题及解决_第2页
java8stream中Collectors.toMap空指针问题及解决_第3页
java8stream中Collectors.toMap空指针问题及解决_第4页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第java8stream中Collectors.toMap空指针问题及解决目录Collectors.toMap空指针问题Collectors.toMap的坑

Collectors.toMap空指针问题

在工作中遇到了一个List转Map的时候的一个NullPointException.

情形很简单,问题出在Collectors.toMap,当key值冲突的时候理论上会按照我们的代码来替换value,但是这里有个小坑

list.stream().collect(Collectors.toMap(it-it.getCategoryId(),it-it.getCategoryImage(),(k1,k2)-k2));

可以看到map在key值冲突merge的时候会要求新的value不能为null.

这意味着,只要传入了(k1,k2)-k2处理key冲突的function,那么当value里存在Null的时候必然会抛NullPointException

Collectors.toMap的坑

按照常规思维,往一个map里put一个已经存在的key,会把原有的key对应的value值覆盖,然而通过一次线上问题,发现Java8中的Collectors.toMap反其道而行之,它默认给抛异常,抛异常...

线上业务代码出现DuplicateKey的异常,影响了业务逻辑,查看抛出异常部分的代码,类似以下写法:

MapInteger,Stringmap=list.stream().collect(Collectors.toMap(Person::getId,Person::getName));

然后list里面有id相同的对象,结果转map的时候居然直接抛异常了。。查源码发现toMap方法默认使用了个throwingMerger

publicstaticT,K,U

CollectorT,,MapK,UtoMap(FunctionsuperT,extendsKkeyMapper,

FunctionsuperT,extendsUvalueMapper){

returntoMap(keyMapper,valueMapper,throwingMerger(),HashMap::new);

privatestaticTBinaryOperatorTthrowingMerger(){

return(u,v)-{thrownewIllegalStateException(String.format("Duplicatekey%s",u));};

}

那么这个throwingMerger是哪里用的呢?

publicstaticT,K,U,MextendsMapK,U

CollectorT,,MtoMap(FunctionsuperT,extendsKkeyMapper,

FunctionsuperT,extendsUvalueMapper,

BinaryOperatorUmergeFunction,

SupplierMmapSupplier){

BiConsumerM,Taccumulator

=(map,element)-map.merge(keyMapper.apply(element),

valueMapper.apply(element),mergeFunction);

returnnewCollectorImpl(mapSupplier,accumulator,mapMerger(mergeFunction),CH_ID);

}

这里传进去的是HashMap,所以最终走的是HashMap的merge方法。merge方法里面有这么一段代码:

if(old!=null){

Vv;

if(old.value!=null)

v=remappingFunction.apply(old.value,value);

else

v=value;

if(v!=null){

old.value=v;

afterNodeAccess(old);

}

else

removeNode(hash,key,null,false,true);

returnv;

}

相信只看变量名就能知道这段代码啥意思了。。如果要put的key已存在,那么就调用传进来的方法。而throwingMerger的做法就是抛了个异常。所以到这里就可以知道写的代码为什么呲了。。

如果不想抛异常的话,自己传进去一个方法即可,上述代码可以改成:

MapInteger,Stringmap=list.stream().collect(Collectors.toMap(Person::getId,Person::get

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论