2017-08-09 35 views
3

我有一個情況如下:如何將Stream方法分配給java 8中的函數?

RowDataSet rdsHavingMaxNumericValue = dataList.stream() 
        .filter(r -> r.getLong(NUMERIC_VALUE) != null) 
        .max((r1, r2) -> r1.getId().compareTo(r2.getId())) 
        .get(); 

我有兩種情況下,我需要找到依據的情況下,無論是最小或最大?我怎樣才能取代函數的第三行調用,以便它直接使用.apply()方法並執行操作?

心中已經成功地分配Collection.max或集合分鐘如下:

BiFunction<List<RowDataSet>, Comparator<RowDataSet>, RowDataSet> mrOrlrOperation = expComponents[0] == 'M' ? Collections::max : Collections::min; 

我用它如下:

RowDataSet rds = mrOrlrOperation.apply(dataList, <some comparator>); 

回答

3

它可能會更簡單,只需使用一個條件:

Stream<?> stream = dataList.stream() 
          .filter(r -> r.getLong(NUMERIC_VALUE) != null); 
Comparator<RowDataSet> c = Comparator.comparingLong(RowDataSet::getId); 
RowDataSet rdsHavingMaxNumericValue = 
       expComponents[0] == 'M' ? stream.max(c).get() : stream.min(c).get(); 

可以存儲在一個單獨的Function最小值/最大值操作,如果你想:

BiFunction<Stream<RowDataSet>, Comparator<RowDataSet>, RowDataSet>> operation = 
      expComponents[0] == 'M' ? (s, c) -> s.max(c).get() : (s, c) -> s.min(c).get(); 

RowDataSet rdsHavingMaxNumericValue = operation.apply(stream, c); 
+0

是啊,看起來像選項,但我想,以避免在運行時 – Ajeetkumar

+0

的情況下查找你是什麼意思? – assylias

+0

我不想執行任何其他操作。我已經把它作爲最後一個選項 – Ajeetkumar

5

選擇使用的min代替max是不是不同的仍然使用max操作,但相反的次序,所以你可以使用

初始化:

Comparator<RowDataSet> c = Comparator.comparingLong(RowDataSet::getId); 
if(expComponents[0] != 'M') c = c.reversed(); 

實際操作

RowDataSet rdsHavingMaxNumericValue = 
    dataList.stream() 
      .filter(r -> r.getLong(NUMERIC_VALUE) != null) 
      .max(c) 
      .get(); 

Rever唱歌的順序沒有性能影響。它只是意味着調用r2.getId().compareTo(r1.getId())代替r1.getId().compareTo(r2.getId()) ...

另一種方法是

Comparator<RowDataSet> c = Comparator.comparingLong(RowDataSet::getId); 
BinaryOperator<RowDataSet> op = expComponents[0] == 'M'? 
           BinaryOperator.maxBy(c): BinaryOperator.minBy(c); 

RowDataSet rdsHavingMaxNumericValue = 
    dataList.stream() 
      .filter(r -> r.getLong(NUMERIC_VALUE) != null) 
      .reduce(op) 
      .get(); 

此預期what min and max would do ...


您可以使用變種創建您BiFunction,例如

變體1:

Function<Comparator<RowDataSet>, Comparator<RowDataSet>> 
    maxOrMin = expComponents[0] == 'M'? Function.identity(): Comparator::reversed; 

BiFunction<List<RowDataSet>, Comparator<RowDataSet>, RowDataSet> mrOrlrOperation 
    = (dataList, comparator) -> dataList.stream() 
             .filter(r -> r.getLong(NUMERIC_VALUE) != null) 
             .max(maxOrMin.apply(comparator)) 
             .get(); 

變2:

Function<Comparator<RowDataSet>, BinaryOperator<RowDataSet>> 
    maxOrMin = expComponents[0] == 'M'? BinaryOperator::maxBy: BinaryOperator::minBy; 

BiFunction<List<RowDataSet>, Comparator<RowDataSet>, RowDataSet> mrOrlrOperation 
    = (dataList, comparator) -> dataList.stream() 
             .filter(r -> r.getLong(NUMERIC_VALUE) != null) 
             .reduce(maxOrMin.apply(comparator)) 
             .get(); 

當然,你也可以生活在一個代碼重複

BiFunction<List<RowDataSet>, Comparator<RowDataSet>, RowDataSet> mrOrlrOperation 
    = expComponents[0] == 'M'? 
     (dataList, comparator) -> dataList.stream() 
              .filter(r -> r.getLong(NUMERIC_VALUE) != null) 
              .max(comparator) 
              .get(): 
     (dataList, comparator) -> dataList.stream() 
              .filter(r -> r.getLong(NUMERIC_VALUE) != null) 
              .min(comparator) 
              .get(); 

在這兩種情況下,條件expComponents[0] == 'M'BiFunction創建時只檢查一次,時從未評估被調用。

0

max是還原操作,那麼您可以使用通用的reduce

public void reducing(BiOperator<...> myFunction) { 
    RowDataSet rdsHavingMaxNumericValue = dataList.stream() 
       .filter(r -> r.getLong(NUMERIC_VALUE) != null) 
       .reduce((r1, r2) -> myFunction.apply(r1,r2)) 
       .get(); 
} 
... 
reducing(Integer::max); 
... 
+0

嗨,我發現你的答案很有趣,但很難完全理解它。 BiFunction參數是整數,整數,整數?在Integer :: max的情況下,您是否錯過了myFunction.apply調用? – Ajeetkumar

+0

是的,我寫得更快一點,糾正... –

+0

BiFunction或BiOperator應該按照你的意思輸入... –