Java 8 has given us new methods with really long signatures like this:
static <T,K,U,M extends Map<K,U>> Collector<T,?,M> toMap(
Function<? super T,? extends K> keyMapper,
Function<? super T,? extends U> valueMapper,
BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier)
What I find odd about this is that wildcards have been used to ensure that the first two parameters are as general as possible, yet the third parameter is just a BinaryOperator<U>
. If they'd been consistent, surely it would be a BiFunction<? super U,? super U,? extends U>
?. Am I missing something? Is there a good reason for this, or did they just want to avoid making an already horrendous signature even worse?
Edit
I understand PECS, and I understand the principle that mergeFunction
should be thought of as a way of taking two U
s and getting back a U
. However it would be useful to be able to have an object that could be reused in many different ways. For example:
static final BiFunction<Number, Number, Double>
MULTIPLY_DOUBLES = (a, b) -> a.doubleValue() * b.doubleValue();
Obviously this is not a BinaryOperator<Double>
, but it could be treated as one. It would be great if you could use MULTIPLY_DOUBLES
as both a BiFunction<Number, Number, Double>
and a BinaryOperator<Double>
, depending on the context. In particular, you could simply pass MULTIPLY_DOUBLES
to indicate that you want a load of double
s to be reduced using multiplication. However the signature for toMap
(and other new methods in Java 8) does not allow for this kind of flexibility.