java8的reduce方法

在 Java 8 中,reduce 是一个流操作方法,用于将流中的元素按照指定的操作进行归约(reduce)操作,最终得到一个结果。

reduce 方法有三种重载形式:

  1. T reduce(T identity, BinaryOperator<T> accumulator)
    这个方法接受一个初始值 identity 和一个二元操作符 accumulator。它使用初始值和流中的元素依次进行二元操作,将结果累积到最终的结果中,并返回最终结果。

  2. <U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner)
    这个方法接受一个初始值 identity、一个累加器函数 accumulator 和一个组合器函数 combiner。它与第一种形式的 reduce 方法类似,但是可以用于并行流的归约操作。在并行流中,流被分成多个子流并行处理,然后使用组合器函数将各个子流的结果合并成最终结果。

  3. Optional<T> reduce(BinaryOperator<T> accumulator)
    这个方法只接受一个二元操作符 accumulator,它没有初始值。它将流中的元素依次进行二元操作,最终返回一个 Optional 对象,表示可能存在的结果。

reduce 方法的使用可以实现多种操作,例如对流中的元素求和、求最大值、求最小值等。下面是一些示例用法:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

// 求和(首次运行前认为a=0,b为第1个元素,第二次运行前a=0+b(上一轮结果),b为第2个元素,依次类推得到结果15)
int sum = numbers.stream().reduce(0, (a, b) -> a + b);
System.out.println(sum); // 输出: 15

// 求最大值
Optional<Integer> max = numbers.stream().reduce(Integer::max);
max.ifPresent(System.out::println); // 输出: 5

// 求乘积(首次运行前认为a=第1个元素,b为第2个元素,第二次运行前a=元素1*元素2(上一轮结果),b为第3个元素)
Optional<Integer> product = numbers.stream().reduce((a, b) -> a * b);
product.ifPresent(System.out::println); // 输出: 120

// 表达式return方式
User1 user1 = new User1(1,"1");
User1 user2 = new User1(2,"2");
User1 user3 = new User1(3,"3");
User1 user4 = new User1(4,"4");
User1 user5 = new User1(5,"5");

List<User1> user1List = Lists.newArrayList();
List<User1> user2List = Lists.newArrayList();

user1List.add(user1);
user1List.add(user2);
user1List.add(user3);
user1List.add(user4);
user1List.add(user5);

final AtomicInteger index = new AtomicInteger(0);
user1List.stream().reduce((a,b)->{
    System.out.println("第"+ (index.getAndAdd(1)) +"轮开始");
    System.out.println("a---->"+JSON.toJSONString(a));
    System.out.println("b---->"+JSON.toJSONString(b));

    User1 user11 = new User1();
    user11.setHigh(a.getHigh()+b.getHigh());
    System.out.println("user11---->"+JSON.toJSONString(user11));
    System.out.println("第"+ (index.get()) +"轮结束");
    System.out.println();

    return user11;
}).ifPresent(user2List::add);

System.out.println("user2List---->"+JSON.toJSONString(user2List));

--输出
第0轮开始
a---->{"high":1,"name":"1"}
b---->{"high":2,"name":"2"}
user11---->{"high":3,"name":"1"}
第1轮结束

第1轮开始
a---->{"high":3,"name":"1"}
b---->{"high":3,"name":"3"}
user11---->{"high":6,"name":"1"}
第2轮结束

第2轮开始
a---->{"high":6,"name":"1"}
b---->{"high":4,"name":"4"}
user11---->{"high":10,"name":"1"}
第3轮结束

第3轮开始
a---->{"high":10,"name":"1"}
b---->{"high":5,"name":"5"}
user11---->{"high":15,"name":"1"}
第4轮结束

user2List---->[{"high":15,"name":"1"}]

从结果可以看到每次的return都作为下一轮的初始值。

在这些示例中,reduce 方法根据提供的操作符对流中的元素进行归约操作,得到最终的结果。注意,reduce 方法返回的结果可能是一个 Optional 对象,因为流中可能没有元素或者操作过程中产生了空值。因此,你可以使用 Optional 的方法来处理可能为空的结果。

以下是更多的示例用法:

List<String> words = Arrays.asList("Hello", "World", "Java", "Programming");

// 拼接字符串
String concatenated = words.stream().reduce("", (a, b) -> a + " " + b);
System.out.println(concatenated); // 输出: " Hello World Java Programming"

// 求字符串列表中最长的单词
Optional<String> longestWord = words.stream().reduce((a, b) -> a.length() > b.length() ? a : b);
longestWord.ifPresent(System.out::println); // 输出: "Programming"

// 检查是否存在以大写字母开头的单词
boolean hasUpperCase = words.stream().anyMatch(s -> Character.isUpperCase(s.charAt(0)));
System.out.println(hasUpperCase); // 输出: true

// 计算数字列表的平均值
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
double average = numbers.stream().mapToDouble(Integer::doubleValue).average().orElse(0);
System.out.println(average); // 输出: 3.0

// 连接两个字符串列表
List<String> list1 = Arrays.asList("Hello", "World");
List<String> list2 = Arrays.asList("Java", "Programming");
List<String> combined = Stream.concat(list1.stream(), list2.stream()).collect(Collectors.toList());
System.out.println(combined); // 输出: ["Hello", "World", "Java", "Programming"]
### Java `Stream` API 中 `reduce` 方法详解 #### 函数签名与基本概念 `reduce` 是 Java 8 引入的流操作之一,旨在通过指定的操作累积流中的元素。此方法有多个重载版本: - 接受两个参数:初始值和累加器函数。 - 只接受一个二元运算符作为参数。 该方法返回的是可选类型的对象 (`Optional`) 或者给定类型的结果[^1]。 #### 基本语法结构 对于带有起始值的情况,其定义如下: ```java T reduce(T identity, BinaryOperator<T> accumulator); ``` 而对于不带起始值的情形,则定义为: ```java Optional<T> reduce(BinaryOperator<T> accumulator); ``` 这里的关键在于理解 `identity` 参数代表什么以及如何实现有效的 `accumulator` 函数来处理数据集合[^2]。 #### 实际应用案例分析 考虑这样一个场景——计算一系列数值列表中所有整数之和。可以采用下面的方式完成这一任务: ```java import java.util.Arrays; import java.util.List; public class ReduceExample { public static void main(String[] args) { List<Integer> numbers = Arrays.asList(1, 2, 3, 4); int sum = numbers.stream() .reduce(0, Integer::sum); // 使用预定义的方法引用 System.out.println("Sum of elements: " + sum); } } ``` 上述例子展示了最简单形式下的 `reduce` 调用方式,其中第一个参数指定了零作为累计过程开始时的状态;第二个参数则是用来指示应该如何把当前状态同下一个输入项结合起来形成新的状态[^3]。 当涉及到更复杂的数据类型比如 `BigDecimal` 类型的时候,同样也可以利用类似的模式来进行聚合操作。例如,在一组发票记录里找到总金额: ```java import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; class Invoice { private final BigDecimal amount; public Invoice(BigDecimal amount) { this.amount = amount; } public BigDecimal getAmount() { return amount; } } public class BigDecimalReduceExample { public static void main(String[] args) { List<Invoice> invoices = new ArrayList<>(); invoices.add(new Invoice(new BigDecimal("97.5"))); invoices.add(new Invoice(new BigDecimal("123.4"))); BigDecimal total = invoices.stream() .map(Invoice::getAmount) .reduce(BigDecimal.ZERO, BigDecimal::add); System.out.println("Total invoice amounts: " + total); } } ``` 在这个实例里面,先是对每张发票调用了 `getAmount()` 获取对应的金额部分,之后再把这些单独的大数相加以得出最终结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值