簡體   English   中英

Java8流並行減少BiFunction累加器

[英]Java8 stream parallel reduce BiFunction accumulator

我正在學習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我的朋友@Stuart Marks說

方法與函數參數匹配以減少約數,因此我們可以使用方法引用。

很抱歉,如果問題很簡單,但任何幫助將不勝感激。

委內瑞拉的最誠摯問候

是的,在使用這種方法引用(特別是“未綁定”方法引用)時,如何對參數進行移位有一個微妙的地方。

讓我們看一下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推斷為ImmutableAverager ,將T推斷為Integer (從int裝箱),此處的方法參考適用。

對於未綁定的方法引用,關鍵點是方法引用是針對實例方法的,但是該方法是使用類名而不是實際實例指定的。 發生這種情況時,接收方將變成方法調用的第一個參數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM