Java8中Stream()流的用法总结
简单的集合遍历
foreach遍历
import java.util.ArrayList;
import java.util.List;
/**
* @author rx
* @date 2022/6/1 17:18
*/
public class Demo1Foreach {
public static void main(String[] args) {
List<String>list=new ArrayList<>();
list.add("w2");
list.add("zh3");
list.add("l4");
list.add("lao6");
list.add("tomas");
for (String s:list){
System.out.println(s);
}
}
}
迭代器遍历
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* @author rx
* @date 2022/6/1 17:18
*/
public class Demo1Foreach {
public static void main(String[] args) {
List<String>list=new ArrayList<>();
list.add("w2");
list.add("zh3");
list.add("l4");
list.add("lao6");
list.add("tomas");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next()+"\t");
}
}
}
有以下场景
- 将集合A根据条件一过滤为子集B;
- 然后再根据条件二过滤为子集C。
先使用Java8以前的做法
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author rx
* @date 2022/6/1 17:18
*/
public class Demo1Foreach {
public static void main(String[] args) {
List<String>list=new ArrayList<>();
List<String>listA=new ArrayList<>();
List<String>listB=new ArrayList<>();
list.add("w2");
list.add("zh3");
list.add("l4");
list.add("lao6");
list.add("tomas");
for (String s:list){
if (s.startsWith("l")){
listA.add(s);
}
}
for (String s:listA){
if (s.length()==4){
listB.add(s);
}
}
for (String s:listB){
System.out.println(s);
}
}
}
使用Stream()流更优的写法
1.场景一:筛选
1.1 基于filter()实现数据过滤
该方法会接收一个返回boolean的函数作为参数,终返回一个包括所有符合条件元素的流。
import jdk.nashorn.internal.ir.IfNode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author rx
* @date 2022/6/1 17:18
*/
public class StreamDemo1 {
public static void main(String[] args) {
List<String>list=new ArrayList<>();
List<String>listA=new ArrayList<>();
List<String>listB=new ArrayList<>();
list.add("w2");
list.add("zh3");
list.add("l4");
list.add("lao6");
list.add("tomas");
list.stream().filter(
name->name.startsWith("l")
).filter(
name->name.length()==4
).forEach(name-> System.out.println(name));
}
}
import jdk.nashorn.internal.ir.IfNode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author rx
* @date 2022/6/1 17:18
*/
public class StreamDemo2 {
public static void main(String[] args) {
List<Student>students=new ArrayList<>();
students.add(new Student("wang2",5,"f"));
students.add(new Student("zh3",3,"f"));
students.add(new Student("li4",5,"f"));
students.stream().filter(student ->
student.getName().length() == 3
&& student.getAge() < 5
).forEach(System.out::println);
}
}
class Student {
public Student(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
'}';
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
private String name;
private int age;
private String gender;
}
1.2基于distinct实现数据去重
import java.util.Arrays;
import java.util.List;
/**
* @author rx
* @date 2022/6/3 10:04
*/
public class StreamDemo3 {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 4, 5, 3, 2, 1, 3, 4, 5, 6, 5, 7, 8);
numbers.stream().distinct().forEach(System.out::println);
}
}
在distinct()内部是基于LinkedHashSet对流中数据进行去重,并终返回一个新的流。
2.切片
2.1基于limit()实现数据截取
import java.util.Arrays;
import java.util.List;
/**
* @author rx
* @date 2022/6/3 10:04
*/
public class StreamDemo5 {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 4, 5, 3, 2, 1, 3, 4, 5, 6, 5, 7, 8);
numbers.stream().limit(3).forEach(System.out::println);
}
}
2.2基于skip()实现数据跳过
import java.util.Arrays;
import java.util.List;
/**
* @author rx
* @date 2022/6/3 10:04
*/
public class StreamDemo6 {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 4, 5, 3, 2, 1, 3, 4, 5, 6, 5, 7, 8);
numbers.stream().skip(3).forEach(System.out::println);
}
}
3.映射
在Stream API中也提供了类似的方法,map()。它接收一个函数作为方法参数,这个函数会被应用到集合中每一个 元素上,并终将其映射为一个新的元素。 案例:获取所有学生的姓名,并形成一个新的集合。
public class StreamDemo7 {
public static void main(String[] args) {
List<Student>students=new ArrayList<>();
students.add(new Student("wang2",5,"f"));
students.add(new Student("zh3",3,"f"));
students.add(new Student("li4",5,"f"));
List<String> stringList = students.stream().map(student -> student.getName()).collect(Collectors.toList());
stringList.stream().forEach(System.out::println);
}
}
4、匹配
boolean anyMatch()、boolean allMatch()、boolean noneMatch()方法。
import jdk.nashorn.internal.ir.IfNode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author rx
* @date 2022/6/1 17:18
*/
public class StreamDemo8 {
public static void main(String[] args) {
List<Student>students=new ArrayList<>();
students.add(new Student("wang2",5,"f"));
students.add(new Student("zh3",3,"f"));
students.add(new Student("li4",5,"f"));
if (students.stream().allMatch(student -> student.getAge()<5)){
System.out.println("have ");
}else {
System.out.println("don't");
}
}
}
5.查找
对于集合操作,有时需要从集合中查找中符合条件的元素,Stream中也提供了相关的API,findAny()和 findFirst(),他俩可以与其他流操作组合使用。findAny用于获取流中随机的某一个元素,findFirst用于获取流中的 第一个元素。至于一些特别的定制化需求,则需要自行实现。
5.1基于findAny()查找元素
案例:findAny用于获取流中随机的某一个元素,并且利用短路在找到结果时,立即结束
public class StreamDemo9 {
public static void main(String[] args) {
List<Student>students=new ArrayList<>();
students.add(new Student("wang2",5,"f"));
students.add(new Student("zh3",3,"f"));
students.add(new Student("li4",5,"f"));
Optional<Student> optionalStudent = students.stream().filter(student -> student.getName().length() == 3).findAny();
System.out.println(optionalStudent.toString());
}
}
5.2基于findFirst()查找元素
findFirst使用原理与findAny类似,只是它无论串行流还是并行流都会返回第一个元素
6、归约
到现在截止,对于流的终端操作,我们返回的有boolean、Optional和List。但是在集合操作中,我们经常会涉及 对元素进行统计计算之类的操作,如求和、求大值、小值等,从而返回不同的数据结果。
6.1基于reduce()进行累积求和
import java.util.Arrays;
import java.util.List;
/**
* @author rx
* @date 2022/6/3 13:34
*/
public class StreamDemo10 {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Integer reduce = list.stream().reduce(0, (x1, x2) -> x1 + x2);
System.out.println(reduce);
}
}
在上述代码中,在reduce里的第一个参数声明为初始值,第二个参数接收一个lambda表达式,代表当前流中的两 个元素,它会反复相加每一个元素,直到流被归约成一个终结果
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
/**
* @author rx
* @date 2022/6/3 13:34
*/
public class StreamDemo11 {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> reduce = list.stream().reduce(Integer::sum);
if (reduce.isPresent()){
System.out.println(reduce);
}else
System.out.println("data is error");
}
}
6.2 获取流中的最大值最小值
public class StreamDemo12 {
public static void main(String[] args) {
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 4, 5, 5, 6, 7, 8, 2, 2, 2, 2);
/**
* 获取集合中的最大值
*/
//方法一
Optional<Integer> max1 = integers.stream().reduce(Integer::max);
if(max1.isPresent()){
System.out.println(max1);
}
//方法二
Optional<Integer> max2 = integers.stream().max(Integer::compareTo);
if(max2.isPresent()){
System.out.println(max2);
}
/**
* 获取集合中的最小值
*/
//方法一
Optional<Integer> min1 = integers.stream().reduce(Integer::min);
if(min1.isPresent()){
System.out.println(min1);
}
//方法二
Optional<Integer> min2 = integers.stream().min(Integer::compareTo);
if(min2.isPresent()){
System.out.println(min2);
}
}
}
7、收集器
通过使用收集器,可以让代码更加方便的进行简化与重用。其内部主要核心是通过Collectors完成更加复杂的计算 转换,从而获取到终结果。并且Collectors内部提供了非常多的常用静态方法,直接拿来就可以了。比方说: toList。
import jdk.nashorn.internal.ir.IfNode;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author rx
* @date 2022/6/1 17:18
*/
public class StreamDemo13 {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("wang2", 5, "f"));
students.add(new Student("zh3", 3, "f"));
students.add(new Student("yx", 88, "f"));
//计算个数,方法一
Long collect = students.stream().collect(Collectors.counting());
System.out.println(collect);
//计算个数,方法二
long count = students.stream().count();
System.out.println(count);
//通过maxBy求最大值,方法一
Optional<Student> optional1 = students.stream().collect(Collectors.maxBy(Comparator.comparing(student -> student.getAge())));
if (optional1.isPresent()) {
System.out.println(optional1);
}
//通过maxBy求最大值,方法二
Optional<Student> max = students.stream().max(Comparator.comparing(Student::getAge));
if (max.isPresent()) {
System.out.println(max);
}
//通过summingInt()进行数据汇总
Integer collect1 = students.stream().collect(Collectors.summingInt(Student::getAge));
System.out.println(collect1);
//通过averagingInt()获取平均值
Double collect3 = students.stream().collect(Collectors.averagingInt(student -> student.getAge()));
System.out.println(collect3);
//通过joining方法进行数据拼接
String collect2 = students.stream().map(Student::getName).collect(Collectors.joining());
System.out.println(collect2);
//复杂结果的返回
IntSummaryStatistics collect4 = students.stream().collect(Collectors.summarizingInt(Student::getAge));
collect4.getSum();
collect4.getMax();
collect4.getCount();
collect4.getAverage();
collect4.getMin();
}
}
8、分组
在数据库操作中,经常会通过group by对查询结果进行分组。同时在日常开发中,也经常会涉及到这一类操作, 如通过性别对学生集合进行分组。如果通过普通编码的方式需要编写大量代码且可读性不好。
对于这个问题的解决,java8也提供了简化书写的方式。通过 Collectors。groupingBy()即可。
public class StreamDemo14 {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("wang2", 5, "m"));
students.add(new Student("zh3", 3, "f"));
students.add(new Student("yx", 88, "m"));
students.add(new Student("sd", 88, "f"));
students.add(new Student("cd", 88, "m"));
Map<String, List<Student>> collect = students.stream().collect(Collectors.groupingBy(Student::getGender));
System.out.println(collect);
//结果: {f=[Student{name='zh3', age=3, gender='f'}, Student{name='sd', age=88, gender='f'}], m=[Student{name='wang2', age=5, gender='m'}, Student{name='yx', age=88, gender='m'}, Student{name='cd', age=88, gender='m'}]}
}
}
8.1多级分组
public class StreamDemo15 {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("wang2", 5, "m"));
students.add(new Student("zh3", 3, "f"));
students.add(new Student("yx", 88, "m"));
students.add(new Student("sd", 88, "f"));
students.add(new Student("cd", 88, "m"));
Map<String, Map<String, List<Student>>> collect = students.stream().collect(Collectors.groupingBy(Student::getGender, Collectors.groupingBy(Student::getGender)));
System.out.println(collect);
//结果:{f={f=[Student{name='zh3', age=3, gender='f'}, Student{name='sd', age=88, gender='f'}]}, m={m=[Student{name='wang2', age=5, gender='m'}, Student{name='yx', age=88, gender='m'}, Student{name='cd', age=88, gender='m'}]}}
}
}

浙公网安备 33010602011771号