gpt4 book ai didi

Java 8流并行reduce BiFunction累加器

转载 作者:行者123 更新时间:2023-12-02 05:21:29 25 4
gpt4 key购买 nike

我正在学习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其参数为 UT并返回 U如上图所示。如果你看accept方法并将接收者视为普通参数,而不是特殊的东西,它采用 ImmutableAverager 类型的参数和类型为 int 的参数,并返回 ImmutableAverager 。所以U推断为 ImmutableAveragerT推断为 Integer (从 int 装箱),并且此处的方法引用有效。

关键点是,对于未绑定(bind)的方法引用,方法引用是对实例方法的,但该方法是使用类名而不是实际实例来指定的。当这种情况发生时,接收者变成方法调用的第一个参数。

关于Java 8流并行reduce BiFunction累加器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26476605/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com