Kehaw

Java-Stream学习第二步:处理流


针对 Stream 的处理就像一个魔法,中间操作会将一个 Stream 转换为另一个 Stream。这些操作处理方式有无数种组合方式,它可以将一个复杂的操作简单化。

处理过程主要是针对 Stream 中的元素进行声明式的转换描述。数据流转到最后的结果取决于中间处理过程的处理方式。

Stream Pipeline 的处理过程可能创建一个新的Stream,该 Stream 的内容可能取决于先前阶段中的元素。而对于map操作(我们将在稍后介绍),新的 Stream 甚至可能包含其他类型的元素。

创建一个流的方法可以参考上一篇文章中所介绍的:

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

System.out.println(list); 

现在,我们将开始针对这些操作进行解释。

Filter

在我们的经验中,filter() 函数是最经常被用到的API之一,它可以将你要处理的元素集合缩小一定的范围,从而为后续的操作减轻压力,例如下面的代码是针对首字母进行过滤:

Stream<String> startsWithT = Stream.of(
   "Monkey", "Lion", "Giraffe", "Lemur"
).filter(s -> s.startsWith("L"));

Limit

limit() 函数可以对 Stream 进行剪裁,从而创建一个新的 Stream。

Stream<String> firstTwo = Stream.of(
   "Monkey", "Lion", "Giraffe", "Lemur"
).limit(2);

此时,新的 Stream 中的元素只有MonkeyLion两个。

Skip

skip() 函数可以选择跳过前面N个元素来直接访问后面的元素,例如我们使用 skip(2) 后可以得到后面两个元素:

Stream<String> firstTwo = Stream.of(
   "Monkey", "Lion", "Giraffe", "Lemur"
).skip(2);

得到GiraffeLemur两个元素。

Distinct

在一些情景下,我们可能不需要重复的元素展现,此时可以使用distinct()函数进行排重处理:

Stream<String> uniqueAnimals = Stream.of(
   "Monkey", "Lion", "Giraffe", "Lemur", "Lion"
).distinct();

最终会输出MonkeyLionGiraffeLemur 四个元素,这里需要注意的是,比对采用的是 equals 函数,如果你的流中包含的是对象的话,可能需要重写 equals 方法。

Sorted

既然是一个数据集合,那么排序自然是非常重要的一个操作方法,sort() 函数可以对元素进行排序操作。

Stream<String> alphabeticOrder = Stream.of(
    "Monkey", "Lion", "Giraffe", "Lemur"
).sorted();

最终输出:GiraffeLemurLionMonkey,注意,这里使用的是Java默认的字符串排序方式。

使用 comparator 进行排序

很多时候我们的 Stream 中包含的是对象集合,因此我们的对象如果想要使用排序功能,则需要实现 comparator 接口,我们这边仅仅使用简单的根据字符串长度进行排序:

Stream<String> lengthOrder = Stream.of(
    "Monkey", "Lion", "Giraffe", "Lemur"
).sorted(Comparator.comparing(String::length));

最终输出:LionLemurMonkeyGiraffe

Map

另外一个最常见的操作就是map()了,Stream 的元素映射到另一个值或类型,它可以将其转换为其他元素。这意味着此操作的结果可以是任何类型的Stream。下面的示例执行从String到String的简单映射,将所有大写字母替换为它们的小写字母。

Stream<String> lowerCase = Stream.of(
    "Monkey", "Lion", "Giraffe", "Lemur"
).map(String::toLowerCase);

Map 转换类型

Stream 中内置了三种简单的数据转换函数,它们分别是:

.mapToInt();
.mapToDouble();
.mapToLong();

因此,这些操作的结果对应于IntStreamDoubleStreamLongStream。下面,我们演示如何使用.mapToInt()函数将动物映射到其名称的长度:

IntStream lengths = Stream.of(
    "Monkey", "Lion", "Giraffe", "Lemur"
).mapToInt(String::length);

最终输出为 [6, 4, 7, 5]

FlatMap

最后一个操作是 flatMap() 函数,它与 Map 操作类似,他不是将泛型 T 转换成返回结果 R,而是将泛型 T 传唤成返回 R。

Stream<Character> chars = Stream.of(
    "Monkey", "Lion", "Giraffe", "Lemur"
).flatMap(s -> s.chars().mapToObj(i -> (char) i));

最终输出:

[M, o, n, k, e, y, L, i, o, n, G, i, r, a, f, f, e, L, e, m, u, r]
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.