319. Java Stream API - 使用终端收集器

文章目录

  • [319. Java Stream API - 使用终端收集器](#319. Java Stream API - 使用终端收集器)
    • [🔍 1. `maxBy()` 和 `minBy()`](#🔍 1. maxBy() 和 minBy())
      • [📌 示例:](#📌 示例:)
      • [🎯 输出:](#🎯 输出:)
    • [➕ 2. `summingInt()` / `summingLong()` / `summingDouble()`](#➕ 2. summingInt() / summingLong() / summingDouble())
      • [📌 示例:](#📌 示例:)
      • [🎯 输出:](#🎯 输出:)
    • [📊 3. `averagingInt()` / `averagingLong()` / `averagingDouble()`](#📊 3. averagingInt() / averagingLong() / averagingDouble())
      • [📌 示例:](#📌 示例:)
      • [🎯 输出:](#🎯 输出:)
    • [📌 小结](#📌 小结)

319. Java Stream API - 使用终端收集器

在 Java 的 Collector API 中,有一组非常有用的 终端收集器(terminal collectors),它们与 Stream API 中的终端操作紧密对应。下面,我们来逐一讲解这些收集器的作用、使用方式,以及它们在实际开发中的典型应用场景。


🔍 1. maxBy() 和 minBy()

这两个收集器用于找出流中的 最大值或最小值 。

它们接收一个 Comparator 作为参数,并返回一个 Optional<T>。如果流为空,那么返回的 Optional 也是空的。

📌 示例:

java 复制代码
import java.util.*;
import java.util.stream.*;

public class MaxMinCollectorDemo {
    public static void main(String[] args) {
        List<String> names = List.of("Alice", "Bob", "Charlie", "David");

        Optional<String> longestName = names.stream()
            .collect(Collectors.maxBy(Comparator.comparingInt(String::length)));

        Optional<String> shortestName = names.stream()
            .collect(Collectors.minBy(Comparator.comparingInt(String::length)));

        System.out.println("Longest name: " + longestName.orElse("N/A"));
        System.out.println("Shortest name: " + shortestName.orElse("N/A"));
    }
}

🎯 输出:

java 复制代码
Longest name: Charlie
Shortest name: Bob

➕ 2. summingInt() / summingLong() / summingDouble()

这三个收集器用于对流中的元素进行求和。

你需要传入一个映射函数,将对象映射为 int、long 或 double,然后进行加总。

📌 示例:

java 复制代码
record Product(String name, double price) {}

public class SumDemo {
    public static void main(String[] args) {
        List<Product> products = List.of(
            new Product("Pen", 1.5),
            new Product("Notebook", 3.0),
            new Product("Pencil", 0.5)
        );

        double totalPrice = products.stream()
            .collect(Collectors.summingDouble(Product::price));

        System.out.println("Total price: " + totalPrice);
    }
}

🎯 输出:

java 复制代码
Total price: 5.0

📊 3. averagingInt() / averagingLong() / averagingDouble()

这些收集器用于计算平均值,也接受一个映射函数,将对象映射为对应数值类型。

不同于 IntStream.average() 等方法,这些收集器始终返回一个 Double 值,即使流为空时也不会抛异常,而是返回 0.0。

📌 示例:

java 复制代码
public class AverageDemo {
    public static void main(String[] args) {
        List<String> words = List.of("cat", "elephant", "tiger", "lion");

        double averageLength = words.stream()
            .collect(Collectors.averagingInt(String::length));

        System.out.println("Average length: " + averageLength);
    }
}

🎯 输出:

java 复制代码
Average length: 5.25

🧠 小贴士:

  • averagingInt() 和 IntStream.average() 的区别在于:
    • IntStream.average() 返回 OptionalDouble,如果流为空会返回 Optional.empty();
    • Collectors.averagingInt() 返回 Double 类型,并且空流默认返回 0.0,更安全。

📌 小结

收集器名称 功能描述 返回类型 空流处理方式
maxBy() / minBy() 获取最大 / 最小元素 Optional<T> 返回空 Optional
summingInt() 等 求和 int / long / double 返回 0
averagingInt() 等 求平均值 Double 返回 0.0

这些收集器在实际开发中非常常见,尤其适用于统计类、报表类、分析类的处理场景。如果你想基于 Stream 结果进行一些汇总、分析操作,这些工具就是你的好帮手!

相关推荐
考虑考虑5 小时前
JDK26中的Map.ofLazy
java·后端·java ee
鶴哥只手遮天8 小时前
Spring AI 2.0.1 深度解析-第 14 章 MCP 服务端(上):注解式实现与工具来源
java·人工智能·开源
鶴哥只手遮天8 小时前
Spring AI 2.0.1 深度解析-第 15 章 MCP 服务端(下):三种协议形态、Streamable 传输与状态管理
java·人工智能·开源
鶴哥只手遮天8 小时前
Spring AI 2.0.1 深度解析-第 16 章 向量存储(上):`VectorStore` 接口体系、`BatchingStrategy`
java·人工智能·开源
鶴哥只手遮天8 小时前
Spring AI 2.0.1 深度解析-第 12 章 工具循环的流式形态、Usage 累加与扩展体系
java·人工智能·开源
鶴哥只手遮天8 小时前
Spring AI 2.0.1 深度解析-第 23 章 模型供应商实现:从 `OpenAiSetup` 到 Bedrock
java·人工智能·开源
鶴哥只手遮天8 小时前
Spring AI 2.0.1 深度解析-第 06 章 内置 Advisor 全景:13 个实现逐个剖到源码级
java·人工智能·开源
鶴哥只手遮天9 小时前
Spring AI 2.0.1 深度解析-第 03 章 消息体系与 Prompt:不可变模型、`ChatOptions` 与模板渲染
java·人工智能·开源
鶴哥只手遮天9 小时前
Spring AI 2.0.1 深度解析-第 24 章 生产实践与 2.x 迁移:陷阱清单、AOT 与调优
java·人工智能·开源
鶴哥只手遮天9 小时前
Spring AI 2.0.1 深度解析-第 10 章 工具调用(中):执行链路、结果转换与工具限制
java·人工智能·开源