《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();
    }
}
相关推荐
面朝大海,春不暖,花不开15 分钟前
自定义Spring Boot Starter的全面指南
java·spring boot·后端
乄夜39 分钟前
嵌入式面试高频(5)!!!C++语言(嵌入式八股文,嵌入式面经)
c语言·c++·单片机·嵌入式硬件·物联网·面试·职场和发展
钡铼技术ARM工业边缘计算机1 小时前
【成本降40%·性能翻倍】RK3588边缘控制器在安防联动系统的升级路径
后端
CryptoPP1 小时前
使用WebSocket实时获取印度股票数据源(无调用次数限制)实战
后端·python·websocket·网络协议·区块链
白宇横流学长1 小时前
基于SpringBoot实现的大创管理系统设计与实现【源码+文档】
java·spring boot·后端
草捏子2 小时前
状态机设计:比if-else优雅100倍的设计
后端
拉不动的猪3 小时前
安卓和ios小程序开发中的兼容性问题举例
前端·javascript·面试
考虑考虑4 小时前
Springboot3.5.x结构化日志新属性
spring boot·后端·spring
涡能增压发动积4 小时前
一起来学 Langgraph [第三节]
后端
sky_ph4 小时前
JAVA-GC浅析(二)G1(Garbage First)回收器
java·后端