《Stream 流操作指南:让数据像奶茶配料一样丝滑流动》

Stream 流

Stream操作

Stream流就是流式处理数据,流的操作有很多种

  • 中间操作(真正处理数据的操作)
    • 中间操作就是执行完返回的是一个流,即可以**继续执行**流操作
    • 敲代码来说,就是使用中间操作的方法,写完继续再.调用其他方法
  • 终止操作(将操作完的结果返回)
    • 敲代码来说,调用终止方法,代码就结束;
操作 函数 说明
中间操作 filter(Predicate) 将结果为false的元素过滤掉
中间操作 map(Function) 转换元素的值,可以用方法引元或者lambda表达式
中间操作 flatMap(Function) 若元素是流,将流摊平为正常元素,再进行元素转换(合并两个流为一个流)
中间操作 limit(long n) 保留前n个元素
中间操作 skip(long n) 跳过前n个元素
中间操作 concat(Stream s1, Stream s2) 将两个流拼接起来
中间操作 distinct() 剔除重复元素
中间操作 sorted() 将Comparable元素的流排序
中间操作 sorted(Comparator) 将流元素按Comparator排序
中间操作 peek(Consumer) 流不变,但会把每个元素传入fun执行,可以用作调试
终结操作 max(Comparator) 取最大值
终结操作 min(Comparator) 取最小值
终结操作 count() 统计元素数量
终结操作 findFirst() 获得流的第一个元素
终结操作 findAny() 返回任意元素
终结操作 anyMatch(Predicate) 任意元素匹配时返回true
终结操作 allMatch(Predicate) 所有元素匹配时返回true
终结操作 noneMatch(Predicate) 没有元素匹配时返回true
终结操作 reduce(Function) 从流中计算某个值,接受一个二元函数作为累积器,从前两个元素开始持续应用它,累积器的中间结果作为第一个参数,流元素作为第二个参数
终结操作 iterator() 迭代器迭代元素
终结操作 forEach(Consumer) lambda的方式迭代
终结操作 forEachOrdered(Consumer) 可以应用在并行流上以保持元素顺序

代码示例:

java 复制代码
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class StreamOperationExamples {
    public static void main(String[] args) {
        // 初始化一个包含 1 到 10 的整数列表
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        // 中间操作:filter(Predicate)
        // filter 方法用于过滤流中的元素,只保留满足 Predicate 条件的元素
        // 这里过滤出列表中所有的偶数
        List<Integer> filteredNumbers = numbers.stream()
               .filter(n -> n % 2 == 0)
               .collect(Collectors.toList());
        // 结果:[2, 4, 6, 8, 10]
        System.out.println("Filtered numbers: " + filteredNumbers);

        // 中间操作:map(Function)
        // map 方法用于对流中的每个元素应用一个函数,将元素转换为另一种形式
        // 这里将列表中的每个元素进行平方操作
        List<Integer> squaredNumbers = numbers.stream()
               .map(n -> n * n)
               .collect(Collectors.toList());
        // 结果:[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
        System.out.println("Squared numbers: " + squaredNumbers);

        // 中间操作:flatMap(Function)
        // flatMap 方法用于将嵌套的流展开成一个单一流
        // 这里将一个包含多个子列表的列表展开成一个包含所有元素的列表
        List<List<Integer>> nestedList = Arrays.asList(
                Arrays.asList(1, 2),
                Arrays.asList(3, 4),
                Arrays.asList(5, 6)
        );
        List<Integer> flattenedList = nestedList.stream()
               .flatMap(List::stream)
               .collect(Collectors.toList());
        // 结果:[1, 2, 3, 4, 5, 6]
        System.out.println("Flattened list: " + flattenedList);

        // 中间操作:limit(long n)
        // limit 方法用于截取流中的前 n 个元素
        // 这里截取列表中的前 3 个元素
        List<Integer> limitedNumbers = numbers.stream()
               .limit(3)
               .collect(Collectors.toList());
        // 结果:[1, 2, 3]
        System.out.println("Limited numbers: " + limitedNumbers);

        // 中间操作:skip(long n)
        // skip 方法用于跳过流中的前 n 个元素
        // 这里跳过列表中的前 3 个元素
        List<Integer> skippedNumbers = numbers.stream()
               .skip(3)
               .collect(Collectors.toList());
        // 结果:[4, 5, 6, 7, 8, 9, 10]
        System.out.println("Skipped numbers: " + skippedNumbers);

        // 中间操作:concat(Stream s1, Stream s2)
        // concat 方法用于将两个流连接成一个流
        // 这里将两个包含整数的流连接成一个新的流
        Stream<Integer> stream1 = Stream.of(1, 2, 3);
        Stream<Integer> stream2 = Stream.of(4, 5, 6);
        List<Integer> concatenatedStream = Stream.concat(stream1, stream2)
               .collect(Collectors.toList());
        // 结果:[1, 2, 3, 4, 5, 6]
        System.out.println("Concatenated stream: " + concatenatedStream);

        // 中间操作:distinct()
        // distinct 方法用于去除流中的重复元素
        // 这里去除列表中的重复元素
        List<Integer> numbersWithDuplicates = Arrays.asList(1, 2, 2, 3, 3, 3);
        List<Integer> distinctNumbers = numbersWithDuplicates.stream()
               .distinct()
               .collect(Collectors.toList());
        // 结果:[1, 2, 3]
        System.out.println("Distinct numbers: " + distinctNumbers);

        // 中间操作:sorted()
        // sorted 方法用于对流中的元素进行自然排序(元素需实现 Comparable 接口)
        // 这里对列表中的元素进行自然排序
        List<Integer> sortedNumbers = numbers.stream()
               .sorted()
               .collect(Collectors.toList());
        // 结果:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        System.out.println("Sorted numbers: " + sortedNumbers);

        // 中间操作:sorted(Comparator)
        // sorted 方法的重载形式,使用自定义的 Comparator 进行排序
        // 这里对列表中的元素进行逆序排序
        List<Integer> reverseSortedNumbers = numbers.stream()
               .sorted(Comparator.reverseOrder())
               .collect(Collectors.toList());
        // 结果:[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
        System.out.println("Reverse sorted numbers: " + reverseSortedNumbers);

        // 中间操作:peek(Consumer)
        // peek 方法用于在流的每个元素上执行一个操作,但不会改变流中的元素
        // 通常用于调试,这里打印出每个元素
        List<Integer> peekedNumbers = numbers.stream()
               .peek(n -> System.out.println("Peeked number: " + n))
               .collect(Collectors.toList());
        // 结果:打印出每个元素,最终集合为 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        System.out.println("Peeked numbers: " + peekedNumbers);

        // 终结操作:max(Comparator)
        // max 方法用于找出流中的最大值,需要传入一个 Comparator 来定义比较规则
        // 这里找出列表中的最大值
        Optional<Integer> maxNumber = numbers.stream()
               .max(Comparator.naturalOrder());
        // 结果:10
        System.out.println("Max number: " + maxNumber.orElse(null));

        // 终结操作:min(Comparator)
        // min 方法用于找出流中的最小值,需要传入一个 Comparator 来定义比较规则
        // 这里找出列表中的最小值
        Optional<Integer> minNumber = numbers.stream()
               .min(Comparator.naturalOrder());
        // 结果:1
        System.out.println("Min number: " + minNumber.orElse(null));

        // 终结操作:count()
        // count 方法用于统计流中元素的数量
        // 这里统计列表中元素的数量
        long count = numbers.stream().count();
        // 结果:10
        System.out.println("Count: " + count);

        // 终结操作:findFirst()
        // findFirst 方法用于获取流中的第一个元素
        // 这里获取列表中的第一个元素
        Optional<Integer> firstNumber = numbers.stream().findFirst();
        // 结果:1
        System.out.println("First number: " + firstNumber.orElse(null));

        // 终结操作:findAny()
        // findAny 方法用于获取流中的任意一个元素
        // 这里获取列表中的任意一个元素
        Optional<Integer> anyNumber = numbers.stream().findAny();
        // 结果:可能是 1 到 10 中的任意一个(这里一般是 1)
        System.out.println("Any number: " + anyNumber.orElse(null));

        // 终结操作:anyMatch(Predicate)
        // anyMatch 方法用于检查流中是否有任意一个元素满足 Predicate 条件
        // 这里检查列表中是否有大于 5 的元素
        boolean anyMatch = numbers.stream().anyMatch(n -> n > 5);
        // 结果:true
        System.out.println("Any number greater than 5: " + anyMatch);

        // 终结操作:allMatch(Predicate)
        // allMatch 方法用于检查流中的所有元素是否都满足 Predicate 条件
        // 这里检查列表中的所有元素是否都大于 0
        boolean allMatch = numbers.stream().allMatch(n -> n > 0);
        // 结果:true
        System.out.println("All numbers greater than 0: " + allMatch);

        // 终结操作:noneMatch(Predicate)
        // noneMatch 方法用于检查流中是否没有任何元素满足 Predicate 条件
        // 这里检查列表中是否没有小于 0 的元素
        boolean noneMatch = numbers.stream().noneMatch(n -> n < 0);
        // 结果:true
        System.out.println("No number less than 0: " + noneMatch);

        // 终结操作:reduce(Function)
        // reduce 方法用于将流中的元素进行累积操作
        // 这里使用 Integer 的 sum 方法将列表中的元素累加起来
        Optional<Integer> sum = numbers.stream().reduce(Integer::sum);
        // 结果:55
        System.out.println("Sum of numbers: " + sum.orElse(null));

        // 终结操作:iterator()
        // iterator 方法用于获取流的迭代器,可用于手动遍历流中的元素
        // 这里使用迭代器遍历列表中的元素并打印
        java.util.Iterator<Integer> iterator = numbers.stream().iterator();
        while (iterator.hasNext()) {
            System.out.print(iterator.next() + " ");
        }
        // 结果:打印出 1 2 3 4 5 6 7 8 9 10
        System.out.println();

        // 终结操作:forEach(Consumer)
        // forEach 方法用于对流中的每个元素执行一个操作
        // 这里使用 Lambda 表达式打印列表中的每个元素
        numbers.stream().forEach(n -> System.out.print(n + " "));
        // 结果:打印出 1 2 3 4 5 6 7 8 9 10
        System.out.println();

        // 终结操作:forEachOrdered(Consumer)
        // forEachOrdered 方法用于在并行流中按顺序对每个元素执行一个操作
        // 这里在并行流中按顺序打印列表中的每个元素
        numbers.parallelStream().forEachOrdered(n -> System.out.print(n + " "));
        // 结果:打印出 1 2 3 4 5 6 7 8 9 10
        System.out.println();
    }
}
相关推荐
欢乐少年19041 小时前
SpringBoot集成Sentry日志收集-3 (Spring Boot集成)
spring boot·后端·sentry
浪九天5 小时前
Java直通车系列13【Spring MVC】(Spring MVC常用注解)
java·后端·spring
uhakadotcom6 小时前
Apache CXF 中的拒绝服务漏洞 CVE-2025-23184 详解
后端·面试·github
uhakadotcom6 小时前
CVE-2025-25012:Kibana 原型污染漏洞解析与防护
后端·面试·github
uhakadotcom6 小时前
揭秘ESP32芯片的隐藏命令:潜在安全风险
后端·面试·github
uhakadotcom6 小时前
Apache Camel 漏洞 CVE-2025-27636 详解与修复
后端·面试·github
uhakadotcom6 小时前
OpenSSH CVE-2025-26466 漏洞解析与防御
后端·面试·github
uhakadotcom6 小时前
PostgreSQL的CVE-2025-1094漏洞解析:SQL注入与元命令执行
后端·面试·github
zhuyasen6 小时前
Go语言开发实战:app库实现多服务启动与关闭的优雅方案
后端·go
ITlinuxP6 小时前
2025最新Postman、Apipost和Apifox API 协议与工具选择方案解析
后端·测试工具·postman·开发工具·apipost·apifox·api协议