Collectors.toMap 有三个重载方法:
toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper);
toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper,
BinaryOperator mergeFunction);
toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper,
BinaryOperator mergeFunction, Supplier mapSupplier);
参数含义分别是:
- keyMapper:Key 的映射函数
- valueMapper:Value 的映射函数
- mergeFunction:当 Key 冲突时,调用的合并方法
- mapSupplier:Map 构造器,在需要返回特定的 Map 时使用
不使用mergeFunction时,如果Key冲突,会抛出java.lang.IllegalStateException,所以有必要定义下key冲突时的合并方法。
Exception in thread "main" java.lang.IllegalStateException: Duplicate key r2
at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133)
at java.util.HashMap.merge(HashMap.java:1254)
at java.util.stream.Collectors.lambda$toMap$58(Collectors.java:1320)
at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1384)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at com.midu.sjyy.api.utils.SyncUtil.main(SyncUtil.java:7709)
例子:
public static void main(String[] args) {
List<IContentCommonNet> iContentCommonNetList = new ArrayList();
IContentCommonNet iContentCommonNet= new IContentCommonNet();
iContentCommonNet.setReferenceKeyword("r1");
iContentCommonNet.setId("1");
iContentCommonNetList.add(iContentCommonNet);
IContentCommonNet iContentCommonNet2= new IContentCommonNet();
iContentCommonNet2.setReferenceKeyword("r2");
iContentCommonNet2.setId("2");
iContentCommonNetList.add(iContentCommonNet2);
IContentCommonNet iContentCommonNet3= new IContentCommonNet();
iContentCommonNet3.setReferenceKeyword("r3");
iContentCommonNet3.setId("2");
//key冲突时会抛出异常
Map<String, String> map =iContentCommonNetList.stream()
.filter(icc -> icc.getReferenceKeyword() != null).
collect(Collectors.toMap(IContentCommonNet::getId,
IContentCommonNet::getReferenceKeyword));
//key冲突时不会抛出异常 因为指定了合并规则
//mergeFunction : (oldValue,newValue)->newValue) 当然也可以写别的
Map<String, String> map =iContentCommonNetList.stream()
.filter(icc -> icc.getReferenceKeyword() != null).
collect(Collectors.toMap(IContentCommonNet::getId,
IContentCommonNet::getReferenceKeyword,
(oldValue,newValue)->newValue));
如果不指定冲突后的合并方法(oldValue,newValue)->newValue,key不冲突的时候就正常转Map ,冲突了就会抛出异常。