关于Stream的使用
引言
Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式。
转自:https://blog.csdn.net/y_k_y/article/details/84633001
特点:
1 . 不是数据结构,不会保存数据。
2. 不会修改原来的数据源,它会将操作后的数据保存到另外一个对象中。(保留意见:毕竟peek方法可以修改流中元素)
3. 惰性求值,流在中间处理过程中,只是对操作进行了记录,并不会立即执行,需要等到执行终止操作的时候才会进行实际的计算。
创建流
// 获取顺序流
Stream stream = new ArrayList().stream();
// 获取并行流
Stream parallelStream = new ArrayList().parallelStream();
// 数组转成流
Integer[] nums = {1,2,3};
Stream<Integer> streamArray = Arrays.stream(nums);
赋值
// of方法直接赋值
Stream<Integer> stream1 = Stream.of(1,2,3,4,5);
stream1.forEach(System.out::println); // 1 2 3 4 5
// iterate生成生成无限顺序有序流,主要作用是抽象迭代逻辑
Stream<Integer> stream2 = Stream.iterate(2, x -> x * 2).limit(5);
stream2.forEach(System.out::println); // 2 4 8 16 32
// generate生成无限顺序无序流,其中每个元素由提供的供应商生成。这适用于生成恒定流,随机元素流等。
Stream<Integer> stream3 = Stream.generate(new Random()::nextInt).limit(2);
stream3.forEach(System.out::println); //15356208 -2042159
筛选与切片
filter:过滤流中的某些元素 limit(n):获取n个元素 skip(n):跳过n元素 distinct:通过流中元素的 hashCode() 和 equals() 去除重复元素
Integer[] nums = {1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10};
Stream<Integer> streamArray = Arrays.stream(nums);
Stream<Integer> result = streamArray
.distinct() // 去重 1 2 3 4 5 6 7 8 9 10
.filter(i -> (i > 2)) // 筛选出值>2的元素 3 4 5 6 7 8 9 10
.skip(2) // 跳过前2个元素 5 6 7 8 9 10
.limit(4); // 获取前4个元素 5 6 7 8
映射
map:接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素
Integer[] nums = {1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10};
Stream<Integer> streamArray = Arrays.stream(nums);
List<String> strings = streamArray
.map(String::valueOf) // 通过String.valueOf()方法将各个元素转为字符串
.collect(Collectors.toList()); // 将流转为List集合
flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
Stream<String> streamArray2 = Stream.of("1.2.3", "4.5.6", "7.8.9");
List<String> result = streamArray2
.flatMap(s -> Arrays.stream(s.split("\\."))) //将流中的每个值都换成另一个流,然后分割
.collect(Collectors.toList());
// 1 2 3 4 5 6 7 8 9
排序
sorted():自然排序,流中元素需实现Comparable接口
List<String> list = Arrays.asList("a", "d", "c", "b", "x");
List<String> result = list.stream()
.sorted()
.collect(Collectors.toList());
// a b c d x
sorted(Comparator com):定制排序,自定义Comparator排序器
Person s1 = new Person("aa", 10);
Person s2 = new Person("bb", 20);
Person s3 = new Person("aa", 30);
Person s4 = new Person("dd", 40);
List<Person> personList = Arrays.asList(s1, s2, s3, s4);
//自定义排序:先按姓名升序,姓名相同则按年龄升序
personList.stream().sorted(
(o1, o2) -> {
if (o1.getName().equals(o2.getName())) {
return o1.getAge() - o2.getAge();
} else {
return o1.getName().compareTo(o2.getName());
}
}
).forEach(person -> System.out.println(person.getName()));
消费
peek:如同于map,能得到流中的每一个元素。但map接收的是一个Function表达式,有返回值;而peek接收的是Consumer表达式,没有返回值
Person s1 = new Person("aa", 10);
Person s2 = new Person("bb", 20);
Person s3 = new Person("aa", 30);
Person s4 = new Person("dd", 40);
List<Person> personList = Arrays.asList(s1, s2, s3, s4);
personList.stream()
.peek(person -> person.setAge(100))
.forEach(person -> System.out.println(person.getName()+":"+person.getAge()));
匹配
allMatch:接收一个 Predicate 函数,当流中每个元素都符合该断言时才返回true,否则返回false
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
// 里面的元素是否都满足>10这个条件
boolean result = integers.stream().allMatch(i -> i > 10); // false
noneMatch:接收一个 Predicate 函数,当流中每个元素都不符合该断言时才返回true,否则返回false
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
// 里面的元素是否都 不 满足>10这个条件
boolean result = list.stream().noneMatch(i -> i > 10); // true
anyMatch:接收一个 Predicate 函数,只要流中存在元素满足该断言则返回true,否则返回false
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 11);
// 里面的元素是否存在满足>10这个条件
boolean result = list.stream().anyMatch(i -> i > 10); // true
findFirst:返回流中第一个元素
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 11);
// Optional对象常用于解决空指针问题
Optional<Integer> optional = list.stream().findFirst();
System.out.println(optional.get()); // 1
count:返回流中元素的总个数
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 11);
Long result = list.stream().count();
System.out.println(result); // 6
max:返回流中元素最大值
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 11);
Integer max = list.stream().max(Integer::compareTo).get(); // 11
min:返回流中元素最小值
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 11);
Integer min = list.stream().min(Integer::compareTo).get(); // 1
reduce
Optional<T> reduce(BinaryOperator<T> accumulator)
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
Optional<Integer> optional = list.stream().reduce((x1, x2) -> x1 + x2);
System.out.println(optional.get()); // 21(为流中元素的和)
// 等效于
// Optional<Integer> optional = list.stream().reduce(Integer::sum);
T reduce(T identity, BinaryOperator<T> accumulator)
identity:返回实例 accumulator:累加器
String[] strings = {"a", "b", "c", "d", "e"};
String reduce2 = Arrays.stream(strings).reduce("", (a, b) -> {
if (!"".equals(a)) {
return a + "|" + b;
} else {
return b;
}
});
/**
* 执行流程:
* 第一个元素identity的值为"",因此a的初始值为"",b的初始值为流中第一个元素"a"
* 第一次执行之后得到结果"a",然后执行结果的值赋给a,流中第二个元素的值"b"赋给b
* 第二次执行之后得到结果"a|b",然后以此类推
*/
System.out.println(reduce2); // a|b|c|d|e
reduce(U identity,BiFunction<U, ? super T, U> accumulator,BinaryOperator<U> combiner)
identity:返回实例 accumulator:累加器 combiner:组合器
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24);
Integer v2 = list.stream().reduce(0,
(x1, x2) -> {
System.out.println("stream accumulator: x1:" + x1 + " x2:" + x2);
return x1 - x2;
},
// 第三个参数---参数的数据类型必须为返回数据类型,改参数主要用于合并多个线程的result值
//(Stream是支持并发操作的,为了避免竞争,对于reduce线程都会有独立的result)
(x1, x2) -> {
System.out.println("stream combiner: x1:" + x1 + " x2:" + x2);
return x1 * x2;
});
System.out.println(v2); // -300
关于Stream的使用的更多相关文章
- SQL Server-聚焦查询计划Stream Aggregate VS Hash Match Aggregate(二十)
前言 之前系列中在查询计划中一直出现Stream Aggregate,当时也只是做了基本了解,对于查询计划中出现的操作,我们都需要去详细研究下,只有这样才能对查询计划执行的每一步操作都了如指掌,所以才 ...
- Node.js:理解stream
Stream在node.js中是一个抽象的接口,基于EventEmitter,也是一种Buffer的高级封装,用来处理流数据.流模块便是提供各种API让我们可以很简单的使用Stream. 流分为四种类 ...
- node中的Stream-Readable和Writeable解读
在node中,只要涉及到文件IO的场景一般都会涉及到一个类-Stream.Stream是对IO设备的抽象表示,其在JAVA中也有涉及,主要体现在四个类-InputStream.Reader.Outpu ...
- nodejs中流(stream)的理解
nodejs的fs模块并没有提供一个copy的方法,但我们可以很容易的实现一个,比如: var source = fs.readFileSync('/path/to/source', {encodin ...
- Node学习笔记(一):stream流操作
NodeJs中谈及较多的可能就是Stream模块了,先写一个简单的ajax回调 $.post("index.php",{data:'aaa',order:'ccc'},functi ...
- Stream
Stream的好处 1.Stream AP的引入弥补了JAVA函数式编程的缺陷.2.Stream相比集合类占用内存更小:集合类里的元素是存储在内存里的,Stream里的元素是在访问的时候才被计算出来. ...
- Stream流
在Node中,存在各式各样不同的数据流,Stream(流)是一个由不同对象实现的抽象接口.例如请求HTTP服务器的request是一个 流,类似于stdout(标准输出):包括文件系统.HTTP 请求 ...
- [LeetCode] Data Stream as Disjoint Intervals 分离区间的数据流
Given a data stream input of non-negative integers a1, a2, ..., an, ..., summarize the numbers seen ...
- [LeetCode] Moving Average from Data Stream 从数据流中移动平均值
Given a stream of integers and a window size, calculate the moving average of all integers in the sl ...
- [LeetCode] Find Median from Data Stream 找出数据流的中位数
Median is the middle value in an ordered integer list. If the size of the list is even, there is no ...
随机推荐
- Makefile目标文件搜索(VPATH和vpath
转载:http://c.biancheng.net/view/7051.html 我们都知道一个工程文件中的源文件有很多,并且存放的位置可能不相同(工程中的文件会被放到不同的目录下),所以按照之前的方 ...
- uvm Register Access Methods(16)
转载: 译文:https://blog.csdn.net/zhajio/article/details/80731435 原文:http://cluelogic.com/2013/02/uvm-tut ...
- best-time-to-buy-and-sell-stock-iii leetcode C++
Say you have an array for which the i th element is the price of a given stock on day i. Design an a ...
- 『学了就忘』Linux基础 — 16、Linux系统与Windows系统的不同
目录 1.Linux严格区分大小写 2.Linux一切皆文件 3.Linux不靠扩展名区分文件类型 4.Linux中所有的存储设备都必须在挂载之后才能使用 5.Windows下的程序不能直接在Linu ...
- Linux系统编程之进程概念
注:本文部分图片来源于网络,如有侵权,请告知删除 1. 什么是进程? 在了解进程概念之前,我们需要先知道程序的概念. 程序,是指编译好的二进制文件,这些文件在磁盘上,并不占用系统资源. 进程,指的是一 ...
- CSP2020-儒略历
大家可以在洛谷提交: 题目描述 为了简便计算,天文学家们使用儒略日(Julian day)来表达时间.所谓儒略日,其定义为从公元前 4713 年 1 月 1 日正午 12 点到此后某一时刻间所经过的天 ...
- Django 小实例S1 简易学生选课管理系统 9 创建课程模型(model)
Django 小实例S1 简易学生选课管理系统 第9节--创建课程模型(model) 点击查看教程总目录 作者自我介绍:b站小UP主,时常直播编程+红警三,python1对1辅导老师. 对于课程模块, ...
- Django 小实例S1 简易学生选课管理系统 4 实现登录页面
Django 小实例S1 简易学生选课管理系统 第4节--实现登录页面 点击查看教程总目录 作者自我介绍:b站小UP主,时常直播编程+红警三,python1对1辅导老师. 本文涉及到的新的额外知识点: ...
- 物联网3D,物业基础设施3D运维,使用webgl(three.js)与物联网设备结合案例。搭建智慧楼宇,智慧园区,3D园区、3D物业设施,3D楼宇管理系统——第八课
写在前面的废话: 很久没有更新文章了,这段时间一直忙于项目落地,虽然很忙,但是感觉没有总结,没有提炼的日子,总是让人感觉飘飘忽忽的. 所幸放下一些事,抽出一些时间,把近期的项目做一些整理与记录.也算是 ...
- [atARC103F]Distance Sums
给定$n$个数$d_{i}$,构造一棵$n$个点的树使得$\forall 1\le i\le n,\sum_{j=1}^{n}dist(i,j)=d_{i}$ 其中$dist(i,j)$表示$i$到$ ...