I'm trying to create an EnumMap
that simply maps the enum's constants to their respective ordinals. I figured I could do so succinctly like so:
private static Map<Rank, Integer> defaultRankOrdering = new EnumMap<>(
Arrays.stream(Rank.values()).collect(
Collectors.toMap(Function::identity, e -> e.ordinal())));
However, the compiler says it cannot infer any of the type variables for toMap
. I don't see why, considering that, per the two-argument signature of 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
should be inferred to be Rank
, as Arrays.stream(Rank.values())
is a Stream<Rank>
, K
should also be inferred to be Rank
, as Function.identity
returns a Function<T, T>
, and U
should be inferred to be Integer
because the return type of Enum.ordinal
is int
, which should be boxed to Integer
in this case.
Any help would be greatly appreciated.
You want Function.identity()
, not Function::identity
:
private static Map<Rank, Integer> defaultRankOrdering = new EnumMap<>(
Arrays.stream(Rank.values()).collect(
Collectors.toMap(Function.identity(), e -> e.ordinal())));
The type of Function::identity
is Supplier<Function<T,T>>
, since it's a method reference for a method that takes nothing and returns a Function<T,T>
.
What you need for your key mapping function is a Function<T,T>
, which is returned by simply calling the method Function.identity()
.
Even if @Eran has pointed out your problem, but I think you need this code snippet, so write it down in my answer:
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)
));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With