mardi 24 mars 2015

Inconsistency in Java 8 method signatures



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 Us 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_AS_DOUBLES as both a BiFunction<Number, Number, Double> and a BinaryOperator<Double>, depending on the context. In particular, you could simply pass MULTIPLY_AS_DOUBLES to indicate that you want a load of doubles 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.




Aucun commentaire:

Enregistrer un commentaire