- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在学习Java 8。我要面对的最困难的事情是Parallel Reduction。以下是我正在学习的用户@Stuart Marks 示例中的代码。
class ImmutableAverager
{
private final int total;
private final int count;
public ImmutableAverager(){this.total = 0;this.count = 0;}
public ImmutableAverager(int total, int count)
{
this.total = total;
this.count = count;
}
public double average(){return count > 0 ? ((double) total) / count : 0;}
public ImmutableAverager accept(final int i)
{
return new ImmutableAverager(total + i, count + 1);
}
public ImmutableAverager combine(final ImmutableAverager other)
{
return new ImmutableAverager(total + other.total, count + other.count);
}
来电
public static void main(String[] args)
{
System.out.println(Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
.parallel()
.reduce(new ImmutableAverager(),
ImmutableAverager::accept,
ImmutableAverager::combine)
.average());
}
这产生了正确的结果,但后来我检查了reduce方法的签名
<U> U reduce(U identity,
BiFunction<U, ? super T, U> accumulator,
BinaryOperator<U> combiner);
如果代码是这样的,我会清楚地理解:
.reduce(new ImmutableAverager(),(a,b)->a.accept(b),(a,b)->a.combine(b))
我不明白怎么做:
ImmutableAverager::accept
可以转换为BiFunction
我的理解是这样的:
ImmutableAverager::accept
将其转换为类似的内容
(ImmutableAverage a)->a.accept(); //but this is a function with 1 parameter not with 2 parameters.
和
ImmutableAverager::merge
可以转换为BinaryOperator
。我的 friend @Stuart Marks 说
这些方法与要减少的函数参数相匹配,因此我们可以使用方法引用。
最佳答案
是的,当使用这种方法引用时,参数的移动方式有一个微妙之处,特别是“未绑定(bind)”方法引用。
让我们看看 reduce()
的第二个参数。它想要
BiFunction<U, ? super T, U> accumulator
所以它的抽象方法的签名是:
U apply(U, T)
(为简洁起见,省略了通配符)。该示例使用了方法引用 ImmutableAverager::accept
它的签名是:
ImmutableAverager accept(int i)
看起来这不起作用,因为 BiFunction
需要两个参数,而 accept
方法只需要一个。但请注意 accept
方法是 ImmutableAverager
上的实例方法类,因此它也隐式地接受一个“接收者”,即调用此方法的对象。对此方法的普通调用可能如下所示:
newAverager = oldAverager.accept(i);
真的,accept
方法实际上需要两个参数,尽管它看起来不像。第一个是接收器,其类型为 ImmutableAverager
,第二个类型为 int
。方法调用语法使得接收者看起来有一些特殊之处,但实际上并没有。就好像这是一个静态方法,调用如下:
newAverager = accept(oldAverager, i);
现在让我们看看它如何与 reduce
一起工作。称呼。有问题的代码是,
reduce(..., ImmutableAverager::accept, ...)
我在这里只显示第二个参数。这需要是 BiFunction
其参数为 U
和T
并返回 U
如上图所示。如果你看accept
方法并将接收者视为普通参数,而不是特殊的东西,它采用 ImmutableAverager
类型的参数和类型为 int
的参数,并返回 ImmutableAverager
。所以U
推断为 ImmutableAverager
和T
推断为 Integer
(从 int
装箱),并且此处的方法引用有效。
关键点是,对于未绑定(bind)的方法引用,方法引用是对实例方法的,但该方法是使用类名而不是实际实例来指定的。当这种情况发生时,接收者变成方法调用的第一个参数。
关于Java 8流并行reduce BiFunction累加器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26476605/
我想链接 BiFunctions,就像下面代码示例中的方法 chainWanted 一样。 BiFunction 将 Function 作为 AndThen 的参数。是否有可能以某种方式链接 BiFu
我遇到了以下问题:一个方法应该接受一个带有 2 个参数的双函数 - 一个是类型 Collection另一个是T ;实际功能实际上可能是 Collection::remove或 Collection::
我有一张 map ,我想在其中数数。在 Java 8 之前,我必须在映射中为每个键放置一个零,然后才能像 map.put(key, map.get(key)+1). 从 Java 8 开始,我现在可以
这个(大大简化的)代码无法为我编译。不知道为什么。返回类型为 Entry?和 null对我来说似乎是一个有效的值(value)。 val foo = BiFunction, Entry?> { foo
我想编写一个接收 List l 的通用方法和两个 BiFunction f1, f2并返回以下表达式的结果: (a0 + a1) * (a2 + a3) *...*(a_{n-1} + an) * a
这个问题已经有答案了: Why doesn't Java 8's ToIntFunction extend Function (2 个回答) 已关闭 4 年前。 我想知道为什么ToDoubleBiFu
传统的函数式语言在列表的初始值和累加器方面考虑减少。在 Java 中,事情更复杂,因为它需要 BinaryOperator。 我想知道我们是否有更好的方法来编写这种函数: public JsonObj
我一直只使用 Java 6,现在正 catch 学习 Java 8 中的新功能。我在这里阅读了这篇文章: http://www.drdobbs.com/jvm/lambda-expressions-i
我正在尝试从列表中识别其前身大于其值的数字。 在 lambda 表达式中,如果我返回 b,它的行为符合预期,但如果我返回 a,它会给出错误的输出。 这两个返回语句有什么区别? List lis
在尝试使用方法引用时,遇到了可以将 concat 方法用作 BiFunction 的情况,据我所知,BiFunction apply 方法需要 2 个输入参数并产生一个结果。然而,concat 方法接
我对在 java (util) 函数中将方法引用作为参数传递有疑问。 我有两个功能 Function f1 = (val) -> { Output o = new Output();
这个问题在这里已经有了答案: How to print two lists together using Stream API java 8? (3 个答案) 关闭 7 年前。 我需要知道如何申请
我创建了一个 GenericFunction 类,它实现了 Function 和 BiFunction。但是无法编译。 public class GenericFunction implements
BiFunction 接口(interface)的定义包含一个方法 apply(T t, U u),它接受两个参数。但是,我不明白这个接口(interface)和方法的用途或目的。我们需要这个接口(i
我一直在尝试使用 Java 进行函数式编程。但是,当我在类中使用功能接口(interface)作为一级变量时,编译时无法识别我的变量。 我试图将其设为 main 中的局部变量,但收到了相同的结果。 我
我正在尝试将我的 Java 类转换为 Kotlin。这是Java代码: Observable.just("Stacey") .zipWith(Observable.just(6), (
我不明白为什么Map.compute()和Map.computeIfPresent()拿BiFunction参数以及Map.computeIfAbsent()一个Function : V comput
考虑以下简化的测试用例: import java.util.AbstractList; import java.util.Collection; import java.util.Iterator;
我不明白为什么Map.compute()和 Map.computeIfPresent()拿BiFunction参数以及 Map.computeIfAbsent()一个Function : V comp
在初始化 TreeMap、TreeSet 等集合时,我们可以添加自定义比较器。代码看起来像这样: Map map1 = new TreeMap<>(new Comparator() { pub
我是一名优秀的程序员,十分优秀!