• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
思想人生从关注生活开始
博客园    首页    新随笔    联系   管理    订阅  订阅

Java流对象stream概述

一、定义与起源

Stream是Java 8 API添加的一个新的抽象概念,称为流(Stream)。它以一种声明性方式处理数据集合,侧重对于源数据计算能力的封装,并且支持序列与并行两种操作方式。Stream流是从支持数据处理操作的源生成的元素序列,这些源可以是数组、文件、集合、函数等。Stream流不是集合元素,也不是数据结构,它并不保存数据,主要目的在于计算,是对集合(Collection)对象功能的增强。

二、原理

  1. 惰性求值:Stream的中间操作是惰性执行的,只有终端操作开始时才会进行计算。这意味着,在调用终端操作之前,中间操作只是对流的操作进行了记录,而并未真正执行。
  2. 无存储:Stream本身不保存数据,它只会在需要时生成结果。
  3. 不可变性:Stream本身不可改变,操作Stream时会生成新的Stream。
  4. 可并行化:通过parallelStream()方法,可以很方便地进行并行操作,利用多核CPU提高性能。

Stream的工作方式是惰性求值,中间操作如map、filter等只是记录操作,而不立即执行。流的终端操作如collect则会触发整个操作链的执行。每个流的操作会以流水线方式运行,数据会依次通过这些流水线,从而提高处理效率。

三、方法

Stream的API由三部分组成:数据源、链式中间操作、终端操作。

       数据源:Stream的数据源可以是集合、数组、I/O通道等。

      你可以从多种来源创建流:

    • 集合框架:如List, Set等可以通过.stream()或.parallelStream()方法创建流。
  • 数组:使用Arrays.stream(array)。
  • 文件:Files.lines(path)可以从文件中读取行作为流。
  • 生成器:Stream.generate(Supplier<T> s)或Stream.iterate(T seed, UnaryOperator<T> f)用于无限流。
  • 静态工厂方法:Stream.of(...)。

      中间操作:返回新的Stream流,可以链式调用。常见的中间操作有:

           

  • filter(Predicate<? super T> predicate):过滤元素。
  • map(Function<? super T, ? extends R> mapper):转换元素。
  • flatMap(Function<? super T, ? extends Stream<? extends R>> mapper):将每个元素映射为另一个流,然后合并这些流。
  • distinct():去除重复元素。
  • sorted() 和 sorted(Comparator<? super T> comparator):排序元素。
  • limit(long maxSize) 和 skip(long n):限制和跳过元素。
  • peek(Consumer<? super T> action):主要用于调试。

 

       终端操作:触发流的计算,并生成结果。常见的终端操作有:

  • forEach(Consumer<? super T> action):对每个元素执行操作。
  • toArray():将流收集到数组中。
  • collect(Collector<? super T, A, R> collector):根据特定规则收集流中的元素。
  • reduce(BinaryOperator<T> accumulator):聚合流中的元素。
  • count():计算流中元素的数量。
  • anyMatch(Predicate<? super T> predicate), allMatch(Predicate<? super T> predicate), noneMatch(Predicate<? super T> predicate):匹配条件。
  • findFirst(), findAny():查找符合条件的第一个元素或任意元素。

 

四、用途

Stream提供了一种简洁、声明式的方式来操作数据集合,极大地提高了代码的可读性和灵活性。它允许开发者在不改变数据源的情况下进行数据处理,能够轻松执行复杂的查找、过滤、筛选等操作,并且可以链式地组合多个操作,形成一个操作管道。

五、使用场景

  1. 过滤和排序:可以对集合中的元素进行过滤和排序操作,例如筛选出年龄大于18岁的用户并按姓名排序。
  2. 并行流处理大数据:对于需要处理大量数据的场景,Stream提供了并行处理的功能,通过parallelStream()方法可以将数据流并行化,提高计算效率。
  3. 自定义聚合:可以使用reduce()操作来实现自定义聚合操作,例如字符串拼接等。

六、各方法示例

  1. filter方法示例:
List<String> list = Arrays.asList("a", "", "b", "", "cc", "x", "dd");
list.stream().filter(item -> !item.trim().isEmpty()).forEach(System.out::println);

 

这段代码使用filter方法过滤出非空字符串,并打印出来。

  1. map方法示例:
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
list.stream().map(x -> x * x).forEach(System.out::println);

 

这段代码使用map方法将每个元素映射为其平方数,并打印出来。

  1. sorted方法示例:

这段代码使用sorted方法对流中的元素进行自然排序,并将结果收集到List中打印出来。

List<Integer> list = Arrays.asList(1, 3, 4, 2, 6, 2);
List<Integer> collect = list.stream().sorted().collect(Collectors.toList());
System.out.println(collect);

 

  1. parallelStream方法示例:
List<Integer> numbers = IntStream.rangeClosed(1, 1000000).boxed().collect(Collectors.toList());
int sum = numbers.parallelStream().reduce(0, Integer::sum);
System.out.println("Sum: " + sum);

 

这段代码使用parallelStream方法将数据流并行化,并计算所有元素的和。

综上所述,Java中的Stream流对象是一种强大的数据处理工具,它提供了丰富的操作方法来处理数据集合,并能够充分利用多核处理器的性能进行并行处理。

posted @ 2024-12-30 14:29  JackYang  阅读(170)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3