Java 8方法签名不一致

Pau*_*ton 10 java java-8

Java 8为我们提供了具有如此长签名的新方法:

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)
Run Code Online (Sandbox Code Playgroud)

我发现奇怪的是,通配符已用于确保前两个参数尽可能通用,但第三个参数只是一个BinaryOperator<U>.如果它们一致,那肯定会是一个BiFunction<? super U,? super U,? extends U>?我错过了什么吗?有没有充分的理由,或者他们只是想避免使已经可怕的签名更糟糕?

编辑

我理解PECS,并且我理解mergeFunction应该被认为是一种获取两个U并且取回一个的方法的原则U.然而,能够拥有可以以许多不同方式重用的对象将是有用的.例如:

static final BiFunction<Number, Number, Double> 
        MULTIPLY_DOUBLES = (a, b) -> a.doubleValue() * b.doubleValue();
Run Code Online (Sandbox Code Playgroud)

显然这不是一个BinaryOperator<Double>,但它可以被视为一个.这将是巨大的,如果你能使用MULTIPLY_DOUBLESBiFunction<Number, Number, Double>BinaryOperator<Double>,根据上下文.特别是,您可以简单地传递MULTIPLY_DOUBLES以指示您希望double使用乘法减少s 的负载.但是toMap(Java 8中的其他新方法)的签名不允许这种灵活性.

Hol*_*ger 3

你是对的,合并操作的功能签名(同样适用于reduce)不需要像BinaryOperator.

\n\n

这不仅可以通过收集器mergeFunction的 的toMap最终Map.merge接受 a 的事实来说明BiFunction<? super V,? super V,? extends V>;您还可以将这样的 a 转换BiFunction为所需的BinaryOperator

\n\n
BiFunction<Number, Number, Double> \n    MULTIPLY_DOUBLES = (a, b) -> a.doubleValue() * b.doubleValue();\nStream<Double> s = Stream.of(42.0, 0.815);\nOptional<Double> n=s.reduce(MULTIPLY_DOUBLES::apply);\n
Run Code Online (Sandbox Code Playgroud)\n\n

或完整通用:

\n\n
public static <T> Optional<T> reduce(\n    Stream<T> s, BiFunction<? super T, ? super T, ? extends T> f) {\n    return s.reduce(f::apply);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

BinaryOperator创建和的最可能的原因UnaryOperator是与这些函数的原始类型版本具有对称性,这些函数没有\xe2\x80\x99t 具有这样的超级接口。

\n\n

在这方面,方法一致的

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

或者

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