概念
Stream(流)是一个来自数据源的元素队列并支持聚合操作
元素是特定类型的对象,形成一个队列
Java中的Stream并不会存储元素,而是按需计算。
数据源 流的来源。 可以是集合,数组,I/O channel, 产生器generator 等。
聚合操作 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。
流的操作步骤
- 创建流,有数据源(集合或者数组产生流)
- 操作流,一系列操作对数据进行运算处理
- 终止流操作,产生结果
创建流的方式
1.list.stream()
2.Arrays.stream()
3.Stream.of()
4.Stream.iterate()
stream流 操作符
操作符 | 描述 |
---|---|
map | 把stream中的元素映射成新的元素输出 |
flatmap | 把多个流连接成一个流 |
limit | 限流操作,比如去流中的前两个数据 |
distint | 去重操作 |
filter | 过滤操作 |
peek | 跳出操作 |
skip | 跳过操作,跳过某些元素 |
sorted | (unordered) 排序操作,对元素排序,前提是实现Comparable接口,当然也可以自定义比较器 |
map() 把stream中的元素映射成新的元素输出
- 代码演示:
/**
* @author liouwb
* @since 2021-04-27
*/
public class Test {
public static void main(String[] args) {
Stream.of(1, 2, 3, 4, 5, 6)
.map(e -> e * 10)
.forEach(System.out::println);
}
}
- 结果
10
20
30
40
50
60
Process finished with exit code 0
flatmap() 将多个Stream映射成一个Stream(和list的addAll()相似)
- 代码演示:
/**
* @author liouwb
* @since 2021-04-27
*/
public class Test {
public static void main(String[] args) {
List<String> strList1 = new ArrayList<>();
strList1.add("张三");
strList1.add("李四");
List<String> strList2 = new ArrayList<>();
strList2.add("悟空");
strList2.add("八戒");
List<String> strList3 = new ArrayList<>();
strList3.add("张飞");
strList3.add("关羽");
Stream.of(strList1, strList2, strList3)
.flatMap(Collection::stream)
.forEach(System.out::println);
}
}
- 结果
张三
李四
悟空
八戒
张飞
关羽
Process finished with exit code 0
distinct() 去重操作
- 代码演示
/**
* @author liouwb
* @since 2021-04-27
*/
public class Test {
public static void main(String[] args) {
Stream.of(1, 2, 2, 3, 4, 5, 6, 7, 7)
.distinct()
.forEach(System.out::println);
}
}
- 结果演示:
1
2
3
4
5
6
7
Process finished with exit code 0
filter() 过滤
- 代码演示:
/**
* @author liouwb
* @since 2021-04-27
*/
public class Test {
public static void main(String[] args) {
Stream.of(1, 2, 2, 3, 4, 5, 6, 7, 7)
.filter(e -> e > 3)
.forEach(System.out::println);
}
}
- 输出结果
4
5
6
7
7
Process finished with exit code 0
limit() 限流操作,获取流中数据的前n个
- 代码演示:
/**
* @author liouwb
* @since 2021-04-27
*/
public class Test {
public static void main(String[] args) {
Stream.of(1, 2, 2, 3, 4, 5, 6, 7, 7)
.limit(3)
.forEach(System.out::println);
}
}
- 结果演示
1
2
2
Process finished with exit code 0
skip() 跳过操作,跳过前n个元素
- 代码演示:
/**
* @author liouwb
* @since 2021-04-27
*/
public class Test {
public static void main(String[] args) {
Stream.of(1, 2, 2, 3, 4, 5, 6, 7, 7)
.skip(4)
.forEach(System.out::println);
}
}
- 结果
4
5
6
7
7
Process finished with exit code 0
skip() 配合limit() 实现分页
- 代码演示:
/**
* @author liouwb
* @since 2021-04-27
*/
public class Test {
public static void main(String[] args) {
Stream.of(1, 2, 2, 3, 4, 5, 6, 7, 7)
.skip(4)
.limit(3)
.forEach(System.out::println);
}
}
- 结果演示:
4
5
6
Process finished with exit code 0
sorted() 对流中数据进行排序操作
- 代码演示:
/**
* @author liouwb
* @since 2021-04-27
*/
public class Test {
public static void main(String[] args) {
Stream.of(5, 9, 3, 2, 30, 3)
.sorted(Integer::compareTo)
.forEach(System.out::println);
}
}
- 结果演示:
2
3
3
5
9
30
Process finished with exit code 0
peek() 跳出操作
终止流的方式
终止符 | 描述 |
---|---|
collect | 收集操作,将所有数据收集起来 |
count | 统计操作 |
findFirst | 查找操作,查找第一个 |
findAny | 查找操作、查找任何一个 |
noneMatch、allMatch、anyMatch | 匹配操作,数据流中是否存在符合条件的元素 返回值为bool 值 |
min、max | 返回数据流中最大最小的值 |
reduce | 规约 |
forEach、forEachOrdered | 遍历 |
toArray | 将数据流的元素转换成数组 |
conllect 收集操作(Collectors工具类),把数据收集到集合中
// Collectors.toList() list搜集器把流的结果转换成list
List<Integer> collect = Stream.of(11, 32, 4, 5, 8, 34)
.collect(Collectors.toList());
count findFirst findAny
- 代码演示:
/**
* @author liouwb
*/
public class StreamTest {
public static void main(String[] args) {
// count统计数据个数
long count = Stream.of(11, 32, 4, 5, 8, 34)
.count();
System.out.println("数据的个数为:" + count);
// findFirst查找第一个元素
// Optional是一个避免空指针的容器类
Optional<Integer> first = Stream.of(11, 32, 4, 5, 8, 34)
.findFirst();
System.out.println("第一个元素为:" + first.get());
// findFirst查找第一个元素
Optional<Integer> any = Stream.of(11, 32, 4, 5, 8, 34)
.findAny();
System.out.println("任意元素:" + any.get());
}
}
- 结果演示:
数据的个数为:6
第一个元素为:11
任意元素:11
Process finished with exit code 0
noneMatch、allMatch、anyMatch
- 代码演示:
/**
* @author liouwb
*/
public class StreamTest {
public static void main(String[] args) {
// anyMatch至少匹配一个元素(大于2)
boolean b = Stream.of(1, 3, 4, 5)
.anyMatch(e -> e > 2);
System.out.println(b);
// allMatch所有元素都匹配(大于2)
boolean b1 = Stream.of(1, 3, 4, 5)
.allMatch(e -> e > 2);
System.out.println(b1);
// noneMatch所有元素都不匹配(大于2)
boolean b2 = Stream.of(1, 3, 4, 5)
.noneMatch(e -> e > 2);
System.out.println(b2);
}
}
- 结果演示:
true
false
false
Process finished with exit code 0
max min
- 代码演示:
/**
* @author liouwb
*/
public class StreamTest {
public static void main(String[] args) {
// max获取流中最大的数据 参数是实现比较方法
Optional<Integer> max = Stream.of(11, 32, 4, 5, 8, 34)
.max(Integer::compareTo);
System.out.println("最大数据为:" + max.get());
// min获取最小值
Optional<Integer> min = Stream.of(11, 32, 4, 5, 8, 34)
.min(Integer::compareTo);
System.out.println("最小值为:" + min.get());
}
}
- 结果演示:
最大数据为:34
最小值为:4
Process finished with exit code 0
reduce
- 代码演示:
/**
* @author liouwb
*/
public class StreamTest {
public static void main(String[] args) {
/***
* reduce 第一个参数是初始值 (这里标记为sum)
* a=0 b=11 a+b=11
* a=11 b=32 a+b=43
* a=43 b=4 a+b=47
* a=47 b=5 a+b=52
* a=52 b=8 a+b=60
* a=60 b=34 a+b=94
* 最后结果等于94
*/
Integer reduce = Stream.of(11, 32, 4, 5, 8, 34)
.reduce(0, (a, b) -> a + b);
System.out.println(reduce);
}
}
- 结果演示:
94
Process finished with exit code 0