文章目录
什么是Stream流
创建Stream流
使用Stream流(常用API)
fliter():按条件进行过滤
limit():按个数进行取出
distinct():去重
skip():跳过前N个流,开始截取
map():对集合元素逐个进行函数操作,映射成全新的一个集合
flatmap():接收一个函数作为参数,将流中的值进行函数操作后,然后把所有流连接成一个流
sorted():排序,可自定义排序
Collectors.groupingBy:按条件进行分组
查找匹配
reduce():将流中的数据反复结合起来得到一个值
终止操作
查找与匹配
归约
Collector 接口中方法
什么是Stream流
在《java8 in action》书中,作者说目前我们在几乎所有开发中都会用到集合,但是目前集合在程序开发中的表现还不够完美,比如你利用集合处理大量数据时,你不得不面对性能问题,不得不考虑进行并行代码的编写,这些工作都是比较繁重的,于是作者便创造了Stream 流。相比较Collection集合来说,Stream在开发中就具有许多独特的优点。
- 以声明式的方式处理数据集合——更简洁,更易读
- 可复合——更灵活
- 可并行——无需写任何多线程代码,Stream API自动处理这些问题,性能更好
注意:map是无法使用stream流,可以将key-value单独取出来做流处理
创建Stream流
有三种方式创建流,静态方法,集合流(常用),数组流。
//静态方法
Stream.of("start",1,2,3,"end");
//集合流
ArrayList
使用Stream流(常用API)
首先创建一个Student类测试
public class Student {
private String name;
public Student(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + ''' +
'}';
}
}
ListemployeeList = Arrays.asList( new Employee(101,"杰斯",29,10000.02), new Employee(101,"杰斯",29,20000.02), new Employee(102,"莫甘娜",19,500.02), new Employee(103,"剑姬",31,4399.02), new Employee(104,"刀妹",25,7777.02), new Employee(105,"提莫",44,100.02) );
fliter():按条件进行过滤
employeeList
.stream()
.filter(x->x.getAge()>20)
.forEach(System.out::println);
取出年龄大于20岁的结果
------------按条件过滤-------------
Employee{id=101, name='杰斯', age=29, salary=10000.02}
Employee{id=101, name='杰斯', age=29, salary=20000.02}
Employee{id=103, name='剑姬', age=31, salary=4399.02}
Employee{id=104, name='刀妹', age=25, salary=7777.02}
Employee{id=105, name='提莫', age=44, salary=100.02}
limit():按个数进行取出
employeeList
.stream()
.limit(2)
.forEach(System.out::println);
取出前两个结果
-------------选择前几个输出------------
Employee{id=101, name='杰斯', age=29, salary=10000.02}
Employee{id=101, name='杰斯', age=29, salary=20000.02}
distinct():去重
employeeList
.stream()
.distinct()
.forEach(System.out::println);
skip():跳过前N个流,开始截取
employeeList
.stream()
.skip(4)
.forEach(System.out::println);
跳过前4个流
--------------跳过前4个流,取后面的流-----------
Employee{id=104, name='刀妹', age=25, salary=7777.02}
Employee{id=105, name='提莫', age=44, salary=100.02}
map():对集合元素逐个进行函数操作,映射成全新的一个集合
employeeList
.stream()
.map(x->x.getSalary()+10000) //将工资都加10000
.forEach(System.out::println);
------------map(接受lambda,将一个函数作为参数,应用到每个元素上,输出新的流)---------
20000.02
30000.02
10500.02
14399.02
17777.02
10100.02
flatmap():接收一个函数作为参数,将流中的值进行函数操作后,然后把所有流连接成一个流
System.out.println("--------------flatmap(连接)-----------");
List list = Arrays.asList("hello", "word");
System.out.println(list); //[hello, word]
List
如果不加flatmap,会输出[ [h,e,l,l,o] [w,o,r,d] ] 两个流,flatmap就是将这两个数组流合并成了一个流
sorted():排序,可自定义排序
employeeList.stream()
.sorted(
(x,y) ->{
if (x.getAge().equals(y.getAge())) {
return x.getSalary().compareTo(y.getSalary());
}else {
return x.getAge().compareTo(y.getAge());
}
}
)
.forEach(System.out::println);
--------------排序(自定义排序)-----------
Employee{id=102, name='莫甘娜', age=19, salary=500.02}
Employee{id=104, name='刀妹', age=25, salary=7777.02}
Employee{id=101, name='杰斯', age=29, salary=10000.02}
Employee{id=101, name='杰斯', age=29, salary=20000.02}
Employee{id=103, name='剑姬', age=31, salary=4399.02}
Employee{id=105, name='提莫', age=44, salary=100.02}
先按年龄排队,再按工资排队
Collectors.groupingBy:按条件进行分组
Map> collect1 = employeeList
.stream()
.collect(Collectors.groupingBy(x -> x.getAge() > 20));
{false=[Employee{id=102, name='莫甘娜', age=19, salary=500.02}],
true=[Employee{id=101, name='杰斯', age=29, salary=10000.02},
Employee{id=101, name='杰斯', age=29, salary=20000.02},
Employee{id=103, name='剑姬', age=31, salary=4399.02},
Employee{id=104, name='刀妹', age=25, salary=7777.02},
Employee{id=105, name='提莫', age=44, salary=100.02}]}
查找匹配
employeeList.stream().anyMatch(x->x.getAge()==29);
employeeList.stream().allMatch(x->x.getAge()==29);
employeeList.stream().noneMatch(x->x.getAge()==29);
employeeList.stream().findFirst();
employeeList.stream().findAny();
employeeList.stream().count();
employeeList.stream().max((x, y) -> x.getAge().compareTo(y.getAge()));
employeeList.stream().min(Comparator.comparing(Employee::getAge));
reduce():将流中的数据反复结合起来得到一个值
//设置初始值
List list = Arrays.asList(1, 2, 3);
System.out.println(list.stream().reduce(100, (x, y) -> x * y));
//不设置初始值
List list = Arrays.asList(2, 2, 3);
System.out.println(list.stream().reduce( (x, y) -> x * y));
600
12
终止操作
会中止流操作,返回结果的函数
查找与匹配
------------map(接受lambda,将一个函数作为参数,应用到每个元素上,输出新的流)---------
20000.02
30000.02
10500.02
14399.02
17777.02
10100.02
System.out.println("--------------flatmap(连接)-----------");
List list = Arrays.asList("hello", "word");
System.out.println(list); //[hello, word]
List
如果不加flatmap,会输出[ [h,e,l,l,o] [w,o,r,d] ] 两个流,flatmap就是将这两个数组流合并成了一个流
sorted():排序,可自定义排序
employeeList.stream()
.sorted(
(x,y) ->{
if (x.getAge().equals(y.getAge())) {
return x.getSalary().compareTo(y.getSalary());
}else {
return x.getAge().compareTo(y.getAge());
}
}
)
.forEach(System.out::println);
--------------排序(自定义排序)-----------
Employee{id=102, name='莫甘娜', age=19, salary=500.02}
Employee{id=104, name='刀妹', age=25, salary=7777.02}
Employee{id=101, name='杰斯', age=29, salary=10000.02}
Employee{id=101, name='杰斯', age=29, salary=20000.02}
Employee{id=103, name='剑姬', age=31, salary=4399.02}
Employee{id=105, name='提莫', age=44, salary=100.02}
先按年龄排队,再按工资排队
Collectors.groupingBy:按条件进行分组
Map> collect1 = employeeList
.stream()
.collect(Collectors.groupingBy(x -> x.getAge() > 20));
{false=[Employee{id=102, name='莫甘娜', age=19, salary=500.02}],
true=[Employee{id=101, name='杰斯', age=29, salary=10000.02},
Employee{id=101, name='杰斯', age=29, salary=20000.02},
Employee{id=103, name='剑姬', age=31, salary=4399.02},
Employee{id=104, name='刀妹', age=25, salary=7777.02},
Employee{id=105, name='提莫', age=44, salary=100.02}]}
查找匹配
employeeList.stream().anyMatch(x->x.getAge()==29);
employeeList.stream().allMatch(x->x.getAge()==29);
employeeList.stream().noneMatch(x->x.getAge()==29);
employeeList.stream().findFirst();
employeeList.stream().findAny();
employeeList.stream().count();
employeeList.stream().max((x, y) -> x.getAge().compareTo(y.getAge()));
employeeList.stream().min(Comparator.comparing(Employee::getAge));
reduce():将流中的数据反复结合起来得到一个值
//设置初始值
List list = Arrays.asList(1, 2, 3);
System.out.println(list.stream().reduce(100, (x, y) -> x * y));
//不设置初始值
List list = Arrays.asList(2, 2, 3);
System.out.println(list.stream().reduce( (x, y) -> x * y));
600
12
终止操作
会中止流操作,返回结果的函数
查找与匹配
--------------排序(自定义排序)-----------
Employee{id=102, name='莫甘娜', age=19, salary=500.02}
Employee{id=104, name='刀妹', age=25, salary=7777.02}
Employee{id=101, name='杰斯', age=29, salary=10000.02}
Employee{id=101, name='杰斯', age=29, salary=20000.02}
Employee{id=103, name='剑姬', age=31, salary=4399.02}
Employee{id=105, name='提莫', age=44, salary=100.02}
先按年龄排队,再按工资排队
Map> collect1 = employeeList .stream() .collect(Collectors.groupingBy(x -> x.getAge() > 20));
{false=[Employee{id=102, name='莫甘娜', age=19, salary=500.02}],
true=[Employee{id=101, name='杰斯', age=29, salary=10000.02},
Employee{id=101, name='杰斯', age=29, salary=20000.02},
Employee{id=103, name='剑姬', age=31, salary=4399.02},
Employee{id=104, name='刀妹', age=25, salary=7777.02},
Employee{id=105, name='提莫', age=44, salary=100.02}]}
查找匹配
employeeList.stream().anyMatch(x->x.getAge()==29);
employeeList.stream().allMatch(x->x.getAge()==29);
employeeList.stream().noneMatch(x->x.getAge()==29);
employeeList.stream().findFirst();
employeeList.stream().findAny();
employeeList.stream().count();
employeeList.stream().max((x, y) -> x.getAge().compareTo(y.getAge()));
employeeList.stream().min(Comparator.comparing(Employee::getAge));
reduce():将流中的数据反复结合起来得到一个值
//设置初始值
List list = Arrays.asList(1, 2, 3);
System.out.println(list.stream().reduce(100, (x, y) -> x * y));
//不设置初始值
List list = Arrays.asList(2, 2, 3);
System.out.println(list.stream().reduce( (x, y) -> x * y));
600
12
终止操作
会中止流操作,返回结果的函数
查找与匹配
//设置初始值
List list = Arrays.asList(1, 2, 3);
System.out.println(list.stream().reduce(100, (x, y) -> x * y));
//不设置初始值
List list = Arrays.asList(2, 2, 3);
System.out.println(list.stream().reduce( (x, y) -> x * y));
600
12
终止操作
会中止流操作,返回结果的函数
查找与匹配
会中止流操作,返回结果的函数
查找与匹配
| allMatch(Predicate p) | 检查是否匹配所有元素 |
| anyMatch(Predicate ) | 检查是否至少匹配一个元素 |
| noneMatch(Predicate p) | 检查是否没有匹配所有元素 |
| findFirst() | 返回第一个元素 |
| findAny() | 返回当前流中的任意元素 |
| count() | 返回流中元素总数 |
| max(Comparator c) | 返回流中最大值 |
| min(Comparator c) | 返回流中最小值 |
| forEach(Consumer c) | stream API 使用内部迭代 |
归约
| reduce () | 将流中元素反复结合起来,得到一个值。 |
Collector 接口中方法
Collector 接口中方法的实现决定了如何对流执行收集操作(如收集到 List、Set、Map)。但是 Collectors 实用类提供了很多静态方法,可以方便地创建常见收集器实例.
Collector 接口中方法的实现决定了如何对流执行收集操作(如收集到 List、Set、Map)。但是 Collectors 实用类提供了很多静态方法,可以方便地创建常见收集器实例.



