《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();
    }
}
相关推荐
最初的↘那颗心2 分钟前
Java HashMap深度解析:原理、实现与最佳实践
java·开发语言·面试·hashmap·八股文
小兔兔吃萝卜8 分钟前
Spring 创建 Bean 的 8 种主要方式
java·后端·spring
热爱23327 分钟前
前端面试必备:原型链 & this 指向总结
前端·javascript·面试
Spider_Man28 分钟前
面试官:你能手写 bind 吗?——JS this 全家桶趣味深度剖析
前端·javascript·面试
Java中文社群32 分钟前
26届双非上岸记!快手之战~
java·后端·面试
whitepure39 分钟前
万字详解Java中的面向对象(一)——设计原则
java·后端
autumnTop39 分钟前
为什么访问不了同事的服务器或者ping不通地址了?
前端·后端·程序员
用户6757049885021 小时前
SQL 判断是否“存在”?99% 的人还在写错!
后端
小奋斗1 小时前
深入浅出:JavaScript中防抖与节流详解
javascript·面试