手把手带你了解Java-Stream流方法学习及总结
作者:Java架构-大仙 发布时间:2023-11-25 19:30:15
前言
Stream是一个来自数据源的元素队列并支持聚合操作,其中具有以下特性:
Stream只负责计算,不存储任何元素,元素是特定类型的对象,形成一个队列
数据源可以实集合、数组、I/O channel、generator等
聚合操作有类似SQL的:filter、map、match、sorted等操作
Stream流的执行类似于懒加载,用户使用时才执行相应操作
可消费性;Stream只能被消费一次,被消费后需要重新生成
本文总结了部分在日常开发中经常接触到的一些Stream流相关的方法,不足之处或有错误欢迎留评,总结的几个方法如下:
void forEach() : 迭代流中的数据
Stream map() : 用于映射每个元素到对应的结果
Stream filter() : 条件过滤器
Stream sorted() : 排序
R collect() : 流数据 -> 集合/数组
待补充…
forEach()
forEach()源码:
void forEach(Consumer<!--? super T--> action);
Stream().forEach() : 迭代流中的数据
forEach() 的返回类型为void,不会产生新的流
举个栗子:
public void testForEach() {
/**
* 使用forEach()内部迭代
* ints()表示整数类型
* limit()表示限制流个数(次数)
*/
Random random = new Random();
random.ints().limit(10).forEach(System.out::println);
}
运行结果:
再举个灵活一点的栗子:
public void testForEach() {
/**
* 使用forEach()转换集合类型,如List->Map
*/
AtomicInteger i = new AtomicInteger();//原子类型
Map<Integer,String> map = new HashMap<>();
List<String> list = new ArrayList<>(Arrays.asList("Hello",",","world"));
list.stream().forEach(s->{
map.put(i.getAndIncrement(),s);
});
}
对于forEach()方法在本人日常开发中常用于:
使用内循环对集合进行遍历
使用foreach方法将List转为Map形式
map()
map()源码:
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
Stream().map() 用于映射每个元素到对应的结果
返回类型为Stream,map()会产生新的流并返回
举个栗子:
public void testMap(){
/**
* map()获取list每个元素的平方值
* distinct()去重操作
* collect()将map()产生的新的流转为List类型
*/
List<Integer> list = Arrays.asList(1,2,3);
list.stream().map(num -> num * num)
.distinct()
.collect(Collectors.toList())
.forEach(System.out::println);
}
filter()
filter()源码:
Stream<T> filter(Predicate<? super T> predicate);
Stream().filter()为条件过滤器
举个栗子:
public void testFilter(){
/**
* filter()过滤空字符串
* count()统计符合条件的个数,返回类型long
*/
List<String> list = new ArrayList<>(Arrays.asList("ab","","abc","","acd"));
long count = list.stream()
.filter(str -> str.isEmpty())
.count();
}
sorted()
sorted()源码:
Stream<T> sorted();
Stream<T> sorted(Comparator<? super T> comparator);
Stream支持两种方式的排序:
无参方法默认为自然排序sorted(Comparator comp) 按自定义比较器进行排序
仍然是举个栗子:
1)无参方法
public void testSorted(){
/**
* sort()无参默认为自然排序
* 返回类型Stream 会产生新的流
*/
List<String> list = new ArrayList<>(Arrays.asList("aaa","ccc","bbb"));
list.stream().sorted().forEach(System.out::println);
}
执行结果:
2)带参方法(User类由name和age组成)
先比较年龄,按从小到大排序
若年龄相等,则按性名自然排序
public void testSorted(){
/**
* sort(Comparator comp)按自定义比较器进行排序
* 返回类型同样是Stream 会产生新的流
*/
List<User> userList = new ArrayList<>(Arrays.asList(
new User("zhangsan",22),
new User("wangwu",22),
new User("badao",32),
new User("kongfu",16)
));
Stream<User> sorted = userList.stream().sorted((x, y) -> {
if (x.getAge() == y.getAge()) { // 使用流中的序列两两进行比较
return x.getName().compareTo(y.getName());
} else {
return x.getAge() - y.getAge();//顺序
// y.getAge() - x.getAge() 为逆序
}
});
sorted.forEach(System.out::println);
}
执行结果:
collect()
collect()源码:
<R> R collect(Supplier<R> supplier,
BiConsumer<R, ? super T> accumulator,
BiConsumer<R, R> combiner);
stream().collect() 由三个参数构成 :
1.Supplier 生产者,返回最终
2.结果BiConsumer<R, ? super T> accumulator,累加器 :
其中 R 为要返回的集合, ? super T 为遍历过程中的每个参数,相当于add操作
3.BiConsumer<R,R> combiner,合并器 :
有并行流时才会使用,相当于将第二部操作形成的list添加到最终的list,addAll操作
举个栗子:
1)new()
public void testCollect(){
Stream<String> stream = Stream.of("hello","world","hello,world");
// new()
List<String> list = stream.collect(Collectors.toList());//List
// 指定集合类型,如ArrayList
ArrayList<String> arrayList = stream.collect(Collectors.toCollection(ArrayList::new));
//Set
stream.collect(Collectors.toSet());
// 指定HashSet
HashSet<String> hashSet = stream.collect(Collectors.toCollection(HashSet::new));
// 拼接字符串
String str = stream.collect(Collectors.joining());
2)new() -> add() -> addAll()
public void testCollect(){
/**
* 参数传递行为相当于: new() -> add() -> addAll()
*/
Stream<String> stream = Stream.of("hello","world","hello,world");
// new() -> add() -> addAll()完整演示
HashMap<String,String> map = stream.collect(HashMap::new,(x,y)->{
x.put(y,y); // x 为集合,y 为当前遍历元素,以当前遍历元素作为kv
},HashMap::putAll);
map.forEach((x,y)->{
System.out.println(x+" : "+y);
});
执行结果:
来源:https://blog.csdn.net/weixin_55932383/article/details/119741519


猜你喜欢
- 实体类package com.whty.entity;public class User {private int id;private S
- 抽象类和抽象方法常用知识点:(1)抽象类作为被继承类,子类必须实现抽象类中的所有抽象方法,除非子类也为抽象类。也就是说,如果子类也为抽象类,
- 系统原来用的是BOSCH_BMA222的gsensor, 现在要求换成使用MMA7660,我们来看一下怎样增加驱动和调试过程。 1. 修改M
- 本文实例讲述了Android使用ActionBar和ViewPager切换页面,分享给大家供大家参考。具体如下:运行效果截图如下:项目布局如
- 首先需要有网络权限,然后我们这里匹配的网络请求是之前封装好的Okhttp。非常的简单方便,直接复制进去,依赖一下包,然后调用方法即可。 这里
- 在实际的应用程序开发中,我们有时需要把 Activity 设置成全屏显示,一般情况下,可以通过两种方式来设置全屏显示效果:其一,通过在代码中
- 本文实例为大家分享了SpringMVC框架实现图片上传与下载的具体代码,供大家参考,具体内容如下1、新建一个Maven webapp项目,引
- 使用RecyclerView越来越多了,基本可以不用listview了,但是这个新的控件谷歌官方似乎设计的没有想listview那样方便快捷
- 封装在如何理解面向对象这篇文章中,提到所谓的封装就是“功能都给你做好了,你不必去理解它是怎么写出来的,直接使用即可。”。但你得清楚一点,那就
- kafka作为一个使用广泛的消息队列,很多人都不会陌生,但当你在网上搜索“kafka 延迟队列”,出
- 前言大家都知道Android Studio目前已经更新到2.0 Preview 6了,作为Google大力推崇的开发工具,相对于Eclips
- 最近准备整理一套关于UI效果的文章,算是对这段时间的一个总结,主要讲Android开发中的UI效果设计模块。初步分为一下几个篇幅:Andro
- 前言在系统运行过程中,可能由于一些配置项的简单变动需要重新打包启停项目,这对于在运行中的项目会造成数据丢失,客户操作无响应等情况发生,针对这
- & 按位运算符,逻辑运算符&& 逻辑运算符相同点:只要有一端为假,则语句不成立假设有三个参数int x = 1;in
- 前言本文告诉大家一个简单的方法从 BBcode 转为 Markdown,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。本文
- 我们知道,spring boot自动配置功能可以根据不同情况来决定spring配置应该用哪个,不应该用哪个,举个例子:Spring的Jdbc
- 本文实例为大家分享了Android studio实现简单计算器的具体代码,供大家参考,具体内容如下需求分析及概要设计目的开发一个简单的计算器
- 目录前言1.设计模式:单例模式1.1 使用时分配,1.2 声明时实例化1.3 双检锁1.4 .net 特性保证的线程安全1.5 使用DI依赖
- 本文实例为大家分享了Java使用poi操作excel的具体代码,供大家参考,具体内容如下依赖poi的jar包,pom.xml配置如下:<
- 首先javascript只有这些个类型:1、Number 在JavaScript中的双精度浮点格式 2、String 双引号的反斜杠转义的U