这是我的代码:
Map<String, Collection<? extends String>> test = listOfTipusIdentificadorPacient.stream()
.collect(Collectors.groupingBy(
TipusIdentificadorPacient::getOid,
Collectors.mapping(TipusIdentificadorPacient::getUse, Collectors.toList())
)
);
Run Code Online (Sandbox Code Playgroud)
我收到此编译消息:
类型不匹配:无法从 Map<String,List> 转换为 Map<String,Collection<? 扩展字符串>>
我不太清楚如何覆盖Collectors.mapping以便:
return:
Map<String,Collection<? extends String>>
instead of:
Map<String,List<String>>
Run Code Online (Sandbox Code Playgroud)
我试图创建另一个通用代码以使其能够编译。
代码是:
return:
Map<String,Collection<? extends String>>
instead of:
Map<String,List<String>>
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
编译错误的原因是:
Map<String, List<String>> mapOfLists = Map.of();
Map<String, Collection<? extends String>> mapOfCollections = Map.of();
Run Code Online (Sandbox Code Playgroud)
考虑到此代码将是合法的:
mapOfCollections.put("", Set.of());
Run Code Online (Sandbox Code Playgroud)
也就是说,您可以将键/值对放在值不是 a 的地方List<String>。因此,您不能分配:
mapOfCollections = mapOfLists;
Run Code Online (Sandbox Code Playgroud)
因为那样你就可以做put上面的事情,导致堆污染。编译器只是阻止你这样做。
// If it were legal...
mapOfCollections = mapOfLists;
mapOfCollections.put("", Set.of());
List<String> list = mapOfLists.get(""); // ClassCastException!
Run Code Online (Sandbox Code Playgroud)
我认为你可以在Collectors.collectingAndThen周围做到这一点toList(),其中“然后”是一个不受约束的演员:
Collectors.collectingAndThen(Collectors.toList(), a -> a)
Run Code Online (Sandbox Code Playgroud)
你不能这样做的原因Function.identity()是签名的组合collectingAndThen和Function.identity():
collectingAndThen(Collector<T,A,R> downstream, Function<R,RR> finisher)意味着函数的输入类型必须与收集器的输出类型匹配 - 在您的情况下,List<String>.Function.identity()是Function<T, T>(没有通配符)。由于函数的输入类型必须是List<String>,所以它的输出类型也是List<String>。a -> a 看起来像恒等函数,但实际上比这更通用:它是一个向上转换的函数,Function<? extends T, T>意味着输出类型不必与输入完全相同,但它可以安全地转换。
因此,在这里,a -> a充当 a Function<List<String>, Collection<? extends String>>(因为List<String>是 的子类型Collection<String>,它是 的子类型Collection<? extends String>)。
| 归档时间: |
|
| 查看次数: |
66 次 |
| 最近记录: |