我正在尝试创建一个EnumMap
,它只是将枚举的常量映射到各自的序数。我想我可以如此简洁地这样做:
private static Map<Rank, Integer> defaultRankOrdering = new EnumMap<>(
Arrays.stream(Rank.values()).collect(
Collectors.toMap(Function::identity, e -> e.ordinal())));
然而,编译器说它无法推断toMap
的任何类型变量。考虑到这一点,我不明白为什么,根据toMap
的两个参数签名:
public static <T, K ,U> Collector<T, ? ,Map<K, U>> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper)
T
应推断为Rank
,因为Arrays.stream(Rank.values())
为Stream<Rank>
,K
也应推断为Rank
,当Function.identity
返回Function<T, T>
时,U
应推断为Integer
,因为Enum.ordinal
的返回类型为int
,应为在这种情况下装箱到Integer
。
非常感谢任何帮助。
答案 0 :(得分:6)
您需要Function.identity()
,而不是Function::identity
:
private static Map<Rank, Integer> defaultRankOrdering = new EnumMap<>(
Arrays.stream(Rank.values()).collect(
Collectors.toMap(Function.identity(), e -> e.ordinal())));
Function::identity
的类型为Supplier<Function<T,T>>
,因为它是一个方法参考,不带任何内容并返回Function<T,T>
。
您的键映射函数需要的是Function<T,T>
,只需调用方法Function.identity()
即可返回。
答案 1 :(得分:3)
即使@Eran指出了您的问题,但我认为您需要此代码段,请在我的回答中写下来:
static Map<Rank, Integer>
defaultRankOrdering = Arrays.stream(Rank.values()).collect(toMap(
Function.identity(),
Enum::ordinal,
(v1, v2) -> v1, // it'is never be used, only support for create an EnumMap
() -> new EnumMap<>(Rank.class)
));