Kehaw

Java-Stream学习第一步:创建流


我们一直在遵守”Learning and doing“的概念,因此该系列所有的代码将会在 GitHub 上找到,在代码仓库中包含了五个单元的 Stream 练习,每个单元都对应一篇文章,而在 README 文件中则提供了有关如何使用源代码的说明。

什么是 Java Stream?

Java Stream 接口最初是在 Java 8 中引入的,并且与 Lambda 表达式一并成为了 Java 的重要里程碑,因为它极大的促进了声明式的编程风格,如果你想要了解更多关于声明式编程的优点,请继续往下阅读。

一个 Java Stream 可以被看做数据流经的管道(参考下图)。在pipeline中的功能将包括:过滤、映射和排序等等。最后,在终端操作中可以将所有的数据写入到指定的数据结构中去,例如List、Array或Map。需要注意的是,每个 Stream 只能使用一次。

一个 Stream Pipeline 包括三个重要组成部分,它们分别是:Stream Source、Operation 和 Terminal Operation。

List<String> list = Stream.of("Monkey", "Lion", "Giraffe","Lemur")
    .filter(s -> s.startsWith("L"))
    .map(String::toUpperCase)
    .sorted()
    .collect(toList());
System.out.println(list);

Stream API 使用起来非常直观,因此无论你之前是否遇到过类似的需求,你都可以非常轻松的去了解 Stream 的操作。

我们从包含四个字符串的列表流开始,每个字符串代表一个非洲动物。然后的操作会从重过滤出以字母 L 开头的动物名,并将名称转换成大写字母,最后进行排序并写入到列表中。最后输出:

[LEMUR, LION]

这里需要注意的是,Stream 流是”惰性“的,即元素是由最终的操作”请求“的(在本例中为.collect()函数调用的时候)。如果最终操作只需要一个元素(例如在最后的时候调用.findFirst()函数),则最多只能有一个元素被请求到,并告知 Stream Source 不再进行对其他元素的操作。

这意味着如果仅仅是创建一个 Stream 一般不会有太大的性能消耗,但是消费这个 Stream 可能会需要耗费较大的性能,这取决于集合中有多少元素。

在这个实例中,Stream Source 是一个 List,当然徐朵其他类型的数据也可以充当 Stream Source,我们将在本文的其余部分介绍一些常用的方法。

Stream Source

Stream 主要适合处理对象的集合,并且可以使用泛型来定义对象类型。虽然有三种特殊的 Stream 实现,它们是: IntStreamLongStreamDoubleStream,但是它们只能处理原始数据类型。

可以通过以下几种方式来生成一个空的Stream:

Stream<T>     Stream.empty()
IntStream     IntStream.empty()
LongStream    LongStream.empty()
DoubleStream  DoubleStream.empty()

通常情况下我们会在定义一个 Stream 的时候同时为其初始化内容,我们通过 IntStream 来看一下如何进行初始化。

IntStreams

我们基于 IntStream.of() 函数来创建一个最简单的流:

IntStream foo = IntStream.of(1, 2, 3);

当然,如果手动的一个个往里面添加,会显得代码很蠢,我们还可以用 rangeClose() 函数来简化我们的操作,如下所示我们添加了从1到9,九个元素:

IntStream foo = IntStream.rangeClose(1, 9);

甚至还有一个更加强大的函数是.iterate()它允许你用更灵活的方式去创建一个 Stream,例如我们获取所有2的次方作为元素放入到流中:

IntStream powersOfTwo = IntStream.iterate(1, i -> i * 2);

当然还有一些比较特殊的方式去创建流,例如基于一个字符串:

IntStream chars = "ABC".chars();

当然,还有一种随机生成的流:

IntStream randomInts = new Random().ints();
数组流(Array)

Stream 基于现有的数据集创建是另外一种方法,我们可以基于一个现有的 Array 数组创建,也可以通过 .of() 函数进行创建:

String[] array = {"Monkey", "Lion", "Giraffe", "Lemur"};
Stream<String> stream2 = Stream.of(array);
Stream<String> stream = Stream.of("Monkey", "Lion", "Giraffe", "Lemur");
集合流(Collection)

当然,我们也可以基于各种集合来创建流:

List<String> list = Arrays.asList("Monkey", "Lion", "Giraffe", "Lemur");
Stream<String> streamFromList = list.stream();
Set<String> set = new HashSet<>(list);
Stream<String> streamFromSet = set.stream();
从文件中读取流

有时候,我们需要从文件中读取数据来形成流,例如:

Stream<String> lines = Files.lines(Paths.get("file.txt"));
Kehaw

👨‍💻Ke Haw 🇨🇳👨‍👩‍👧‍👦

风吹云散去,夜色好观星
Java | 前端 | 大数据

专注于 Spring Cloud 微服务架构与数据处理,研究一切与Java相关的开发技术,包括一部分前端技术。

目前的工作主要是关于B2B大宗商品在线交易领域的数据处理。如果对本站的部分内容感兴趣,请通过邮件、Twitter联系我🤝。

Fork me on Gitee
基于Spring Security + OAuth2 + JWT 的权限认证(一) Java-Stream学习第四步:数据处理 Java-Stream学习第三步:终端操作 Java-Stream学习第二步:处理流 Java-Stream学习第一步:创建流 Electron使用串口通信 Electron下调用DLL文件 国外SaaS服务供应商都是干什么的:Part1 为什么Kafka会丢失消息 Spring Boot中使用JSR380验证框架
Description lists
Kehaw's blog
Site description
人初做事,如鸡伏卵,不舍而生气渐充;如燕营巢,不息而结构渐牢;如滋培之木,不见其长,有时而大;如有本之泉,不舍昼夜,盈科而后进,放乎四海。
Copyright
© 2014 Copyright Kehaw | All rights reserved.