当前位置:网站首页>One bite of Stream(1)
One bite of Stream(1)
2022-07-20 05:43:00 【程序员·小李】
举个例子,stream在做什么?
List<String> threeHighCaloricDishNames = menu.stream()
.filter(d -> d.getCalories() > 300)
.map(Dish::getName)
.limit(3)
.collect(toList());
stream方法从一个List中构造出一个流,filter对其中的元素进行了过滤,满足Calories大于300的才会被留下,map是直接取到他们的Name,limit留下了前3个数据,collect用于将流收集起来,构造一个新的List出来
流只能被使用一次
这样直接用Stream接收,反复使用的方式是不允许的。
中间步骤与结束步骤
以上面的示例为例,先进行了筛选、映射、提取前三个,最够从流中构造了一个新的List。前三个步骤都是在基于流进行数据处理,而最后一个操作是将符合条件的流中的元素收集起来。因而分别称之为中间步骤和结束步骤。
filter
1. 使用filter过滤符合条件的元素
List<Dish> vegetarianMenu = menu.stream()
.filter(Dish::isVegetarian)
.collect(toList());
filter内部是一个Predicate语句,输入为Element的类型数据,输出是Boolean
这个操作还算简单,将符合条件的数据过滤出来,聚合成新的List。
2. 过滤,并去除重复的元素
List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);
numbers.stream()
.filter(i -> i % 2 == 0)
.distinct()
.forEach(System.out::println);
经过filter后,留下了所有的偶数,但是还存在重复的元素,使用distinct去重(依赖hashCode和equals方法的实现)
最后并没有构造新的list,而是依次遍历并打印了各个元素
3. 元素截断limit
通过limit(N)可以截断前N个符合要求的数据,最大不超过N,如果实际元素的数量小于N则取Min(size(), N)
List<Dish> dishes = menu.stream()
.filter(d -> d.getCalories() > 300)
.limit(3)
.collect(toList());
先进行了一次过滤,然后截断前3条数据,构造成一个新的List
4. 元素跳过skip(N)
List<Dish> dishes = menu.stream()
.filter(d -> d.getCalories() > 300)
.skip(2)
.collect(toList());
通过skip(N)可以跳过前N个数据,如果实际元素的数量小于N则跳过全部,返回空的数据。
先进行一次筛选,然后在筛选后的数据中跳过前两条,最后收集到List中。
map
map用于类型的转换,例如Stream中的元素是A类型,我想取出每个元素的B属性,可以使用map。再例如,Stream中的元素是A类型,我想把每个元素转换成B类型,也可以使用map
例如,Dish有个属性是name, 我想获取每个元素的名称,组装成一个List:
List<String> dishNames = menu.stream()
.map(Dish::getName)
.collect(toList());
或者有一串字符串,我想获取每个字符串的长度:
List<String> words = Arrays.asList("Java8", "Lambdas", "In", "Action");
List<Integer> wordLengths = words.stream()
.map(String::length)
.collect(toList());
既然map是中间操作,我们可以多次使用(先获取name,然后取name的长度):
List<Integer> dishNameLengths = menu.stream()
.map(Dish::getName)
.map(String::length)
.collect(toList());
flatMap
flatMap的用法较为特殊,它具备映射、并且可以将多个流合并为一个流。
假如我们想获取一个字符串数组中["Hello", "World"],不重复的字母["H", "e", "l", "o", "W", "r", "d"],生成一个List出来,怎么办?
words.stream()
.map(word -> word.split(""))
.distinct()
.collect(toList());
先针对每个字符串,使用string.split分割成字符串数组,然后去重可以吗?显然不符合要求,因为distinct是针对每个字符串数组操作的,达不到去重的效果,结果集也不是List<String>, 而是List<String[]>
换一种思路,将每个数组转换成流,这样总可以合并了吧
words.stream()
.map(word -> word.split(""))
.map(Arrays::stream)
.distinct()
.collect(toList());
每个单词分割成字符串数组,然后将每个字符串数组转换成字符串流,最后去重,合并。想法不错,但是转换成字符串流的时候,我们会发现,每个字符串数组生成的是一个单独的流,最终的结果是List<Stream<String>>而不是我们想要的LIst<String>.
那有没有办法把每个Stream合并到一起呢?flatMap就可以
List<String> uniqueCharacters = words.stream()
.map(w -> w.split(""))
.flatMap(Arrays::stream)
.distinct()
.collect(Collectors.toList());
边栏推荐
- 初步基础jvm
- 学习记录五
- 聪明人的游戏提高篇:第三章第二课:因子个数(dcount)
- uni-app - App 平台内嵌网页物理手机自带返回键失效解决方案(内嵌的 webview 网页 H5 打包后手机物理返回键无效直接退出应用了)
- 聪明人的游戏提高篇:第三章第一课:isbn (ISBN码)
- uni-app - 插件[App云打包]安装失败!(app打包时显示app云打包插件安装失败)解决方案
- 回到原点:重新开始学习
- 请问一下 flink1.15 flinksql kafka topic如果不提前创建提交作业就会失败
- 解决错误:could not find ‘xxxTest‘
- Title of graduation thesis on Thermal Power Engineering
猜你喜欢
随机推荐
Model graduation thesis of Construction Engineering Surveying and mapping
Chapter006 LCD display of FPGA learning
STM32CubeMX的正交编码器encoder
Compose实现webView文件选择
"Dry goods experiment" Huawei DHCP + single arm routing experiment
[Unity脚本优化]Optimizing scripts in Unity games——2019以下
聪明人的游戏提高篇:第三章第一课:grid(格子位置)
Graduation thesis title of power system and automation [selected]
并发编程day01
学习记录十三
uni-app - App 平台内嵌网页物理手机自带返回键失效解决方案(内嵌的 webview 网页 H5 打包后手机物理返回键无效直接退出应用了)
Chapter003 FPGA learning PWM LED breathing lamp
微信H5记录
UGUI——Text和TextEffect
时间格式化
好玩的猜数游戏(不是二分查找!四位数)
cocos2dx 引擎中的一些技巧
【STM32F103RCT6】CAN通信
色彩空间(2)—— YUV
Model graduation thesis on traffic safety management