Java Streams:覆盖 Collectors.mapping 的返回类型
这是我的代码:
Map<String, Collection<? extends String>> test = listOfTipusIdentificadorPacient.stream()
.collect(Collectors.groupingBy(
TipusIdentificadorPacient::getOid,
Collectors.mapping(TipusIdentificadorPacient::getUse, Collectors.toList())
)
);
我收到此编译消息:
我不太清楚如何覆盖Collectors.mapping以便:
return:
Map<String,Collection<? extends String>>
instead of:
Map<String,List<String>>
我试图创建另一个通用代码以使其能够编译。
代码是:
return:
Map<String,Collection<? extends String>>
instead of:
Map<String,List<String>>
有任何想法吗?
回答
编译错误的原因是:
Map<String, List<String>> mapOfLists = Map.of();
Map<String, Collection<? extends String>> mapOfCollections = Map.of();
考虑到此代码将是合法的:
mapOfCollections.put("", Set.of());
也就是说,您可以将键/值对放在值不是 a 的地方List<String>。因此,您不能分配:
mapOfCollections = mapOfLists;
因为那样你就可以做put上面的事情,导致堆污染。编译器只是阻止你这样做。
// If it were legal...
mapOfCollections = mapOfLists;
mapOfCollections.put("", Set.of());
List<String> list = mapOfLists.get(""); // ClassCastException!
我认为你可以在Collectors.collectingAndThen周围做到这一点toList(),其中“然后”是一个不受约束的演员:
Collectors.collectingAndThen(Collectors.toList(), a -> a)
你不能这样做的原因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>)。
THE END
二维码