无法为Collectors.toMap推断类型变量

时间:2017-07-09 20:23:33

标签: java lambda java-8 java-stream collectors

我正在尝试创建一个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

非常感谢任何帮助。

2 个答案:

答案 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)
));