《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();
    }
}
相关推荐
武子康3 小时前
Java-80 深入浅出 RPC Dubbo 动态服务降级:从雪崩防护到配置中心秒级生效
java·分布式·后端·spring·微服务·rpc·dubbo
PAK向日葵3 小时前
【算法导论】如何攻克一道Hard难度的LeetCode题?以「寻找两个正序数组的中位数」为例
c++·算法·面试
舒一笑3 小时前
我的开源项目-PandaCoder迎来史诗级大更新啦
后端·程序员·intellij idea
@昵称不存在4 小时前
Flask input 和datalist结合
后端·python·flask
zhuyasen5 小时前
Go 分布式任务和定时任务太难?sasynq 让异步任务从未如此简单
后端·go
东林牧之5 小时前
Django+celery异步:拿来即用,可移植性高
后端·python·django
超浪的晨6 小时前
Java UDP 通信详解:从基础到实战,彻底掌握无连接网络编程
java·开发语言·后端·学习·个人开发
AntBlack6 小时前
从小不学好 ,影刀 + ddddocr 实现图片验证码认证自动化
后端·python·计算机视觉
Pomelo_刘金6 小时前
Clean Architecture 整洁架构:借一只闹钟讲明白「整洁架构」的来龙去脉
后端·架构·rust
双力臂4047 小时前
Spring Boot 单元测试进阶:JUnit5 + Mock测试与切片测试实战及覆盖率报告生成
java·spring boot·后端·单元测试