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()是签名的组合collectingAndThenFunction.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>)。


以上是Java Streams:覆盖 Collectors.mapping 的返回类型的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>