Java 8 method signature inconsistency

Java 8 gives us a new method. It's really a long signature, 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)

I find it strange that wildcards have been used to ensure that the first two parameters are as general as possible, but the third parameter is only a binary operator u. if they are consistent, it will certainly be a bifunction super u super u extension U > Did I miss anything? Is there a good reason for this, or is it just to avoid making the already terrible signature worse?

edit

I understand pecs. I understand that merging functions should be considered as a principle of taking two US and returning one U However, it would be useful to have an object that can 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 binaryoperator < < double >, but it can be regarded as a If you can use multi_ Double, as bifunction < number, double > and binaryoperator < double >, depends on the context In particular, you can simply pass multiple_ Double to indicate that you want to use multiplication to reduce the multiple of doubling However, the signing of tomap (and other new methods in Java 8) does not allow this flexibility

Solution

You are correct. The function signature of merge operation (also applicable to reduce) does not need an interface like binaryoperator

This can be explained not only by the fact that the mergefunction of the tomap collector will eventually be in map Accept bifunction at merge you can also convert such bifunctions to the required binaryoperator:

BiFunction<Number,Double> 
    MULTIPLY_DOUBLES = (a,b) -> a.doubleValue() * b.doubleValue();
Stream<Double> s = Stream.of(42.0,0.815);
Optional<Double> n=s.reduce(MULTIPLY_DOUBLES::apply);

Or fully universal:

public static <T> Optional<T> reduce(
    Stream<T> s,BiFunction<? super T,? super T,? extends T> f) {
    return s.reduce(f::apply);
}

The most likely reason for creating binaryoperator and unaryoperator is that they are symmetrical with the original type versions of these functions without such a super interface

In this regard, the approach is consistent

Stream. reduce(BinaryOperator< T) > IntStream. reduce(IntBinaryOperator) > DoubleStream. reduce(DoubleBinaryOperator) > LongStream. reduce(LongBinaryOperator)

or

> Arrays. parallelPrefix(T [] array,BinaryOperator< T> op)> Arrays. parallelPrefix(int [] array,IntBinaryOperator op)> Arrays. parallelPrefix(double [] array,DoubleBinaryOperator op)> Arrays. parallelPrefix(long [] array,LongBinaryOperator op)

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>