Java 8 Stream.reduce() 使用示例

英文原文地址:https://mkyong.com/java8/java-8-stream-reduce-examples/



翻譯:高行行

在 Java 8 中,Stream.reduce() 合併流的元素併產生單個值。

使用 for 循環的簡單求和運算。

<code>  int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int sum = 0;
for (int i : numbers) {
sum += i;
}

System.out.println("sum : " + sum); // 55
/<code>

相當於 Stream.reduce()

<code>  int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

// 1st argument, init value = 0
int sum = Arrays.stream(numbers).reduce(0, (a, b) -> a + b);

System.out.println("sum : " + sum); // 55
/<code>

或方法引用 Integer::sum

<code>int sum = Arrays.stream(numbers).reduce(0, Integer::sum); // 55
/<code>

Integer.java

<code>    /**
* Adds two integers together as per the + operator.
*
* @param a the first operand
* @param b the second operand
* @return the sum of {@code a} and {@code b}
* @see java.util.function.BinaryOperator
* @since 1.8

*/
public static int sum(int a, int b) {
return a + b;
}
/<code>

1. 方法簽名

1.1 查看Stream.reduce()方法簽名:

Stream.java

<code>T reduce(T identity, BinaryOperator accumulator);
/<code>

IntStream.java

<code>int reduce(int identity, IntBinaryOperator op);
/<code>

LongStream.java

<code>long reduce(int identity, LongBinaryOperator op);
/<code>
  • identity = 默認值或初始值。
  • BinaryOperator = 函數式接口,取兩個值併產生一個新值。(注: java Function 函數中的 BinaryOperator 接口用於執行 lambda 表達式並返回一個 T 類型的返回值)

1.2 如果缺少identity參數,則沒有默認值或初始值,並且它返回 optional。

Stream.java

<code>Optional reduce(BinaryOperator accumulator);
/<code>

2. 更多例子

2.1 數學運算。

<code>int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

int sum = Arrays.stream(numbers).reduce(0, (a, b) -> a + b); // 55
int sum2 = Arrays.stream(numbers).reduce(0, Integer::sum); // 55

int sum3 = Arrays.stream(numbers).reduce(0, (a, b) -> a - b); // -55
int sum4 = Arrays.stream(numbers).reduce(0, (a, b) -> a * b); // 0, initial is 0, 0 * whatever = 0
int sum5 = Arrays.stream(numbers).reduce(0, (a, b) -> a / b); // 0
/<code>

2.2 最大和最小

<code>int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

int max = Arrays.stream(numbers).reduce(0, (a, b) -> a > b ? a : b); // 10
int max1 = Arrays.stream(numbers).reduce(0, Integer::max); // 10

int min = Arrays.stream(numbers).reduce(0, (a, b) -> a < b ? a : b); // 0
int min1 = Arrays.stream(numbers).reduce(0, Integer::min); // 0
/<code>

2.3 連接字符串。

<code>  String[] strings = {"a", "b", "c", "d", "e"};

// |a|b|c|d|e , the initial | join is not what we want
String reduce = Arrays.stream(strings).reduce("", (a, b) -> a + "|" + b);

// a|b|c|d|e, filter the initial "" empty string
String reduce2 = Arrays.stream(strings).reduce("", (a, b) -> {
if (!"".equals(a)) {
return a + "|" + b;
} else {
return b;

}
});

// a|b|c|d|e , better uses the Java 8 String.join :) (最好使用 Java 8 的 String.join)
String join = String.join("|", strings);
/<code>

3. Map & Reduce

一個簡單的 map 和 reduce 示例,用於從發票 List 中求 BigDecimal 的和。

JavaReduce.java

<code>package com.mkyong;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.List;

public class JavaReduce {

public static void main(String[] args) {

// 發票集合
List<invoice> invoices = Arrays.asList(
new Invoice("A01", BigDecimal.valueOf(9.99), BigDecimal.valueOf(1)),
new Invoice("A02", BigDecimal.valueOf(19.99), BigDecimal.valueOf(1.5)),
new Invoice("A03", BigDecimal.valueOf(4.99), BigDecimal.valueOf(2))
);

BigDecimal sum = invoices.stream()
.map(x -> x.getQty().multiply(x.getPrice())) // map,對集合中的元素進行操作
.reduce(BigDecimal.ZERO, BigDecimal::add); // reduce,將上一步得到的結果進行合併得到最終的結果

System.out.println(sum); // 49.955
System.out.println(sum.setScale(2, RoundingMode.HALF_UP)); // 49.96 使用setScale方法進行四捨五入

}

}


class Invoice {

// 發票號碼
String invoiceNo;
// 價格
BigDecimal price;
// 數量
BigDecimal qty;

// getters, stters n constructor
}
/<invoice>/<code>

輸出

<code>49.955
49.96/<code>

[1] mkyong: https://mkyong.com/author/mkyong/


分享到:


相關文章: