水滴石穿-JDK8中Stream类的常用用法

本文最后更新于:April 21, 2022 pm

积土成山,风雨兴焉;积水成渊,蛟龙生焉;积善成德,而神明自得,圣心备焉。故不积跬步,无以至千里,不积小流无以成江海。齐骥一跃,不能十步,驽马十驾,功不在舍。面对悬崖峭壁,一百年也看不出一条裂缝来,但用斧凿,能进一寸进一寸,能进一尺进一尺,不断积累,飞跃必来,突破随之。

目录

Stream 是用函数式编程方式在集合类上进行复杂操作的工具,其集成了Java 8中的众多新特性之一的聚合操作,开发者可以更容易地使用Lambda表达式,并且更方便地实现对集合的查找、遍历、过滤以及常见计算等。

类和添加数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Student {
int no;
String name;
String sex;
float height;

public Student(int no, String name, String sex, float height) {
this.no = no;
this.name = name;
this.sex = sex;
this.height = height;
}
}

Student stuA = new Student(1, "A", "M", 184);
Student stuB = new Student(2, "B", "G", 163);
Student stuC = new Student(3, "C", "M", 175);
Student stuD = new Student(4, "D", "G", 158);
Student stuE = new Student(5, "E", "M", 170);
List<Student> list = new ArrayList<>();
list.add(stuA);
list.add(stuB);
list.add(stuC);
list.add(stuD);
list.add(stuE);

filter

比较常用。filter方法对原Stream按照指定条件过滤,在新建的Stream中,只包含满足条件的元素,将不满足条件的元素过滤掉。

1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) {
List<Student> ans = list.stream().filter(it -> it.sex.equals("G")).collect(Collectors.toList());
for(Student it: ans){
System.out.println(it.name+" "+it.sex);
}

}

//
B G
D G

it -> it.sex.equals("G") 中的it表示形参,后面跟的是处理语句。.collect(Collectors.toList()) 表示把Stream转成List集合。

map

map方法将对于Stream中包含的元素使用给定的转换函数进行转换操作,新生成的Stream只包含转换生成的元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public static void main(String[] args) {
List<String> str = new ArrayList<>();
str.add("a");
str.add("a");
str.add("bab");
str.add("bab");
str.add("ab");
str.add("abc");

List<String> ans = str.stream().map(it -> it.toUpperCase()).collect(Collectors.toList());
for(String it: ans){
System.out.println(it);
}

}

//
A
A
BAB
BAB
AB
ABC

distinct

去重。distinct方法以达到去除掉原Stream中重复的元素,生成的新Stream中没有没有重复的元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static void main(String[] args) {
List<String> str = new ArrayList<>();
str.add("a");
str.add("a");
str.add("bab");
str.add("bab");
str.add("ab");
str.add("abc");

List<String> ans = str.stream().distinct().collect(Collectors.toList());
for(String it: ans){
System.out.println(it);
}

}

//
a
bab
ab
abc

limit

limit方法将截取原Stream,截取后Stream的最大长度不能超过指定值N。如果原Stream的元素个数大于N,将截取原Stream的前N个元素;如果原Stream的元素个数小于或等于N,将截取原Stream中的所有元素。

1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) {
List<Student> ans = list.stream().limit(2).collect(Collectors.toList());
for(Student it: ans){
System.out.println(it.no);
}

}

//
1
2

sorted

sorted方法将对原Stream进行排序,返回一个有序列的新Stream。sorterd有两种变体sorted(),sorted(Comparator),前者将默认使用Object.equals(Object)进行排序,而后者接受一个自定义排序规则函数(Comparator),可按照意愿排序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static void main(String[] args) {
List<Integer> nu = new ArrayList<>();
nu.add(2);
nu.add(6);
nu.add(1);
nu.add(3);
nu.add(5);

List<Integer> ans = nu.stream().sorted().collect(Collectors.toList());
for(Integer it: ans){
System.out.println(it);
}

}

//
1
2
3
5
6

max

1
2
3
4
5
6
7
8
9
10
11
12
13
public static void main(String[] args) {
List<Integer> nu = new ArrayList<>();
nu.add(2);
nu.add(6);
nu.add(1);
nu.add(3);
nu.add(5);

Optional<Integer> max = nu.stream().max((o1, o2) -> o1-o2);
//Optional<Integer> max = nu.stream().max((o1, o2) -> o2-o1); //1
System.out.println(max.get()); //6

}

min

1
2
3
4
5
6
7
8
9
10
11
12
13
public static void main(String[] args) {
List<Integer> nu = new ArrayList<>();
nu.add(2);
nu.add(6);
nu.add(1);
nu.add(3);
nu.add(5);

Optional<Integer> max = nu.stream().min((o1, o2) -> o1-o2);
//Optional<Integer> max = nu.stream().min((o1, o2) -> o2-o1); //6
System.out.println(max.get()); //1

}