Java Streams中修改Collectors.mapping返回类型解决类型不匹配问题
问题根源
Java泛型具备不变性:虽然List<String>是Collection<String>的子类,但Map<String, List<String>>不属于Map<String, Collection<? extends String>>的子类型,编译器无法自动完成类型转换。
另外你写的测试代码存在一处笔误:Stream元素类型是Map.Entry,所以mapping的取值函数应该用Map.Entry::getValue而非Pair::getValue。
可行解决方案
方案1:显式指定收集容器类型(最稳妥)
使用Collectors.toCollection直接声明收集结果为Collection<? extends String>类型,底层实际仍用ArrayList存储,无额外性能损耗:
Map<String, Collection<? extends String>> test = listOfTipusIdentificadorPacient.stream() .collect(Collectors.groupingBy( TipusIdentificadorPacient::getOid, Collectors.mapping( TipusIdentificadorPacient::getUse, Collectors.<String, Collection<? extends String>>toCollection(ArrayList::new) ) ));
测试代码修改后版本:
Stream<Map.Entry<String, String>> streamOfPairedStrings = Stream.of(); Map<String, Collection<? extends String>> test = streamOfPairedStrings .collect(Collectors.groupingBy( Map.Entry::getKey, Collectors.mapping( Map.Entry::getValue, Collectors.<String, Collection<? extends String>>toCollection(ArrayList::new) ) ));
方案2:显式指定collect方法泛型参数
直接在collect调用时声明返回类型,强制编译器完成类型推导:
Map<String, Collection<? extends String>> test = listOfTipusIdentificadorPacient.stream() .<Map<String, Collection<? extends String>>>collect(Collectors.groupingBy( TipusIdentificadorPacient::getOid, Collectors.mapping(TipusIdentificadorPacient::getUse, Collectors.toList()) ));
方案3:通配符适配转换
如果可以修改接收变量的泛型签名,直接加一层通配符就能兼容,完全不需要修改收集逻辑:
Map<String, ? extends Collection<? extends String>> test = listOfTipusIdentificadorPacient.stream() .collect(Collectors.groupingBy( TipusIdentificadorPacient::getOid, Collectors.mapping(TipusIdentificadorPacient::getUse, Collectors.toList()) ));
如果必须严格匹配Map<String, Collection<? extends String>>的签名,也可以用collectingAndThen做安全转换:
Map<String, Collection<? extends String>> test = listOfTipusIdentificadorPacient.stream() .collect(Collectors.collectingAndThen( Collectors.groupingBy( TipusIdentificadorPacient::getOid, Collectors.mapping(TipusIdentificadorPacient::getUse, Collectors.toList()) ), Collections::unmodifiableMap ));
内容的提问来源于stack exchange,提问作者Jordi
相关产品推荐
相关产品推荐

