Java
Python前端运维数据库
Java
Java
  • 新特性
    • Record
    • Optional
  • 面向对象
    • 面向对象基础
    • 构造方法
    • 继承与多态
    • 接口
    • 修饰符
    • 代码块
    • 接口(Interface)
    • 枚举类
  • IO流
    • IO
      • 字节流
      • 字符流
      • 缓冲流
      • 转换流
      • 操作ZIP
      • File 对象
    • NIO
      • Channel和Buffer
      • 异步文件通道AsynchronousFileChannel
      • Selector
      • Path/Files/Pipe
  • 反射
  • 内存分配
  • 集合
    • 简介
    • List
    • Set
    • Map
    • EnumMap
  • 日期与时间
    • Date和Calendar
    • Java8 新时间 ✨
      • LocalDateTime
      • ZonedDateTime
      • Duration
    • 时间格式化
      • SimpleDateFromat
      • DateTimeFormatter ✨
    • Instant
    • 实践
  • 网络编程
    • IP 地址
    • 网络模型
    • TCP 编程
    • UDP 编程
    • HTTP 编程
  • 加密和安全
  • 并发编程
    • 多线程
    • 线程与进程的区别
    • 线程组和线程优先级
    • 线程池
    • 线程锁
  • 异步任务
    • Future
    • CompletableFuture
      • 开启异步任务
      • 串行任务方法
      • 并行任务方法
      • 任务结束方法
      • 异常处理方法
      • 查看状态方法
      • 设置任务结果方法
  • 执行系统命令
  • Stream 流
    • Stream 流的创建
    • Stream 流串行与并行
    • Stream 流中间操作
    • Stream 流终端操作
  • Lambda 表达式
    • Lambda 表达式简介
    • Lambda 表达式语法
    • 方法引用
  • String
  • StringBuffer
由 GitBook 提供支持
在本页
  • 简介
  • Stream 操作分类
  • 中间操作
  • 终端操作
  • Stream 的特点

这有帮助吗?

Stream 流

上一页执行系统命令下一页Stream 流的创建

最后更新于11个月前

这有帮助吗?

简介

Java 8 引入了一个全新的 API:Stream API,它可以极大地提高 Java 程序员的编程效率和程序的性能。Stream API 是一个来自于函数式编程的概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。

Stream 将要处理的元素集合看作一种流,流在管道中传输,通过管道可以对流进行某些计算和操作,比如筛选、排序、聚合等。 每一次操作都在原数据流的基础上生成一个新的流,这样就可以通过多次操作,将操作结果组合起来,最后得到想要的结果。

Stream API 提供了串行和并行两种模式进行操作,可以大大提高程序的运行效率。

Stream 操作分类

Stream 操作可以分为两种类型:中间操作(Intermediate Operations)和终端操作(Terminal Operations)。

中间操作

一个流后面可以跟随零个或多个中间操作。其目的主要是打开流,做出某种程度的数据映射、过滤等操作,然后返回一个新的流,交给下一个操作使用。这类操作都是惰性化的(lazy),就是说,仅调用到这类方法,并没有真正开始流的遍历。而是当有终端操作时,才开始执行。

中间操作主要有map、filter、distinct、sorted、peek、limit、skip、parallel、sequential 等。

中间操作又可以分为两种:

  • 无状态操作:数据的处理不依赖于前面的数据,比如 map、filter 等操作。

  • 有状态操作:数据的处理依赖于前面的数据,比如 sorted、distinct 等操作。

// 转换为大写
List<String> list = Arrays.asList("apple", "banana", "orange", "pear", "strawberry");
List<String> result = list.stream()
        .map(String::toUpperCase)
        .collect(Collectors.toList());
System.out.println(result);
// 输出:[APPLE, BANANA, ORANGE, PEAR, STRAWBERRY]
// 按照字符串长度排序
List<String> list = Arrays.asList("apple", "banana", "orange", "pear", "strawberry");
List<String> result = list.stream()
        .sorted((s1, s2) -> s1.length() - s2.length())
        .collect(Collectors.toList());
System.out.println(result);
// 输出:[pear, apple, banana, orange, strawberry]

终端操作

一个流只能有一个终端操作,当这个操作执行后,流就被使用“光”了,无法再被操作。所以这必定是流的最后一个操作。终端操作的执行,才会真正开始流的遍历,并且会生成一个结果,或者一个副作用。

终端操作主要有forEach、count、collect、reduce、min、max、findFirst、anyMatch、allMatch、noneMatch、toArray 等。

对于流的终端操作,可以分为两种:

  • 非短路操作:对整个流的所有元素进行处理,比如forEach、count、collect、reduce等操作。

  • 短路操作:对流中的前 N 个元素进行处理,比如findFirst、limit 等操作。

// 统计长度大于 5 的元素个数
List<String> list = Arrays.asList("apple", "banana", "orange", "pear", "strawberry");
long count = list.stream()
        .filter(s -> s.length() > 5)
        .count();
System.out.println(count);
// 输出:3
// 找到第一个长度大于 5 的元素
List<String> list = Arrays.asList("apple", "banana", "orange", "pear", "strawberry");
Optional<String> result = list.stream()
      .filter(s -> s.length() > 5)
      .findFirst();
System.out.println(result.orElse("No result"));
// 输出:strawberry

Stream 的特点

Stream 的特点可以归纳为:

  • 不是数据结构,不会保存数据:Stream 是一种从源数据中按照特定规则取数据的方式,而不是一个数据容器。

  • 不支持索引访问:Stream 只能对数据进行一次遍历,遍历过一次后即用尽,就像流水一样只能消费一次。

  • 不会改变源对象:Stream 的操作不会修改源数据对象,而是返回一个持有结果的新 Stream。

  • 自动优化:Stream 会自动进行优化,比如延迟执行(lazy)和短路(short-circuiting)。只有在执行终端操作时,中间操作才会被执行。

  • 链式调用:通过操作管道的方式,可以对操作进行链式调用,使代码更加简洁和易读。

  • 支持并行操作:Stream 的操作可以是串行的,也可以是并行的,通过并行流可以利用多核处理器的优势,提高性能。

Stream 操作分类