当前位置: 首页 > 知识库问答 >
问题:

为什么Stream.Reduce采用BinaryOperator而不是BiFunction?[副本]

任繁
2023-03-14

对于我的具体情况,我想在约简中使用函数合成;例如:

BiFunction<ImmutableSet<Integer>, ImmutableSet<Integer>, Sets.SetView<Integer>> f = Sets::intersection;
Function<Sets.SetView<Integer>, ImmutableSet<Integer>> g = Sets.SetView::immutableCopy;
BiFunction<ImmutableSet<Integer>, ImmutableSet<Integer>, ImmutableSet<Integer>> biFunction = f.andThen(g);
ImmutableSet<Integer> intersection = Stream.of(ImmutableSet.of(1, 2, 3), ImmutableSet.of(1, 2), ImmutableSet.of(4))
    .reduce(biFunction)
    .orElse(ImmutableSet.of());

这有一个编译错误:

argument mismatch BiFunction cannot be converted to BinaryOperator

相反,我需要做的是:

ImmutableSet<Integer> intersection = Stream.of(ImmutableSet.of(1, 2, 3), ImmutableSet.of(1, 2), ImmutableSet.of(4))
    .reduce((a, b) -> Sets.intersection(a, b).immutableCopy())
    .orElse(ImmutableSet.of());

但是,这就失去了composition提供的无点样式。

为什么流API是这样设计的?BinaryOperatorBiFunction,所以用超类型声明Reduce方法的参数不是更有意义吗?

共有1个答案

段干楚青
2023-03-14

reduce操作必须采用相同类型的参数并返回相同类型。如果没有,就会出现类型不匹配。这正是binaryoperator的含义:binaryoperator 扩展了bifunction

您可以创建bifunction而不是使用lambda。然后创建BinaryOperator:

import java.util.function.BinaryOperator;
import java.util.function.BiFunction;
import java.util.function.Function;

import java.util.stream.Stream;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;

public class StackOverflowTest {
  public static void main(String[] args) {

    BiFunction<ImmutableSet<Integer>, ImmutableSet<Integer>, Sets.SetView<Integer>> f = Sets::intersection;
    Function<Sets.SetView<Integer>, ImmutableSet<Integer>> g = Sets.SetView::immutableCopy;

    BiFunction<ImmutableSet<Integer>, ImmutableSet<Integer>, ImmutableSet<Integer>> biFunction = f.andThen(g);

    BinaryOperator<ImmutableSet<Integer>> biOperator = biFunction::apply;

    ImmutableSet<Integer> intersection =
       Stream.of(ImmutableSet.of(1, 2, 3),
                 ImmutableSet.of(1, 2),
                 ImmutableSet.of(1, 4)) // added a 1
             .reduce(biOperator)
             .orElse(ImmutableSet.of());

    System.out.println(intersection);

/*
prints:
[1]
*/
  }
}
 类似资料:
  • 我有一个想要减少的枚举值流。如果流为空或包含不同的值,我希望。如果它只包含一个值(的多个实例),我想要那个值。 我试着用减音来做: 不幸的是,这不起作用,因为当结果为时,这个reduce方法抛出一个。有人知道为什么会这样吗?为什么不是有效的结果? 现在,我是这样解决的: 在这起作用的同时,我并不满足于这种“弯路”。我喜欢减少,因为它似乎是合适的,把所有的东西都放进一个流。 有没有人能想出一个替代r

  • 我非常熟悉这个框架,从一开始我就喜欢它。 有一件事我还不能完全理解,那就是为什么打字有时会中断。 特别是对于这个问题,,我不确定为什么没有使用,起初我认为可能是int32/int16/float等之间的行为差异。。但(对我来说)这在透明化中是没有意义的。 因此,从lib来看,它需要很好地处理数学问题。 我的问题是关于语义的,为什么决定使用而不是?

  • 我看过一些代码,其中人们使用了带有两个“!”的条件子句s 这是我能找到的一些例子。 使用有什么好处超过?

  • 我看到一些教程建议在Kotlin中使用val而不是var。我相信val在Java中就像常量,对吗?那么,如果建议使用它而不是var,我们如何更改它的值? 更新:例如:为什么我要使用val而不是var声明类成员(变量或字段)?而在Java中,它就像:

  • 问题内容: 我已经在Android代码中使用FloatBuffers一段时间了(从一些opengles教程中复制了它),但是我无法确切地理解此构造是什么以及为什么需要它。 例如,我在许多人的代码和android教程中看到了以下代码(或类似代码): 就我所知,这似乎是冗长和混乱的,我只是说它们只是一个浮点数的包装而已。 问题: 与任何其他类型的float集合或简单数组相反,这种类型的类(ByteBu

  • 问题内容: 听说您应该在样式表中使用em而不是像素来定义尺寸和距离。所以问题是,为什么在CSS中定义样式时应该使用em而不是px?有一个很好的例子可以说明这一点吗? 问题答案: 我问这个问题的原因是,我忘记了如何使用em,因为我在CSS中愉快地编程时已经很久了。人们没有注意到我把这个问题笼罩了,因为我并不是在谈论字体本身的大小。我对如何在页面上的 任何给定块元素 上定义样式更感兴趣。 正如Henr