前言
这篇文章简单总结一下Stream中的常用方法,,当然一般都是和Lambda配合着使用的。
对Lambda不熟悉的同学,可以参考这篇进行入门对Lambda的理解,Lambda真是越用越爽
如果刚刚入门Lambda,但对Consumer、Supplier、Predicate与Function不怎么熟悉的同学,可以参考这篇文章快速理解Consumer、Supplier、Predicate与Function
如果已经对Lambda很熟悉的同学,但对其执行原理不太懂的同学,可以参考我的这篇文章Lambda执行原理
先给出一个示例
下面有五个学生,放入到集合中
@Data
@AllArgsConstructor
class Student {
private String name;
private Integer age;
}
Student a = new Student("a", 20);
Student b = new Student("b", 18);
Student c = new Student("c", 22);
Student d = new Student("d", 19);
Student e = new Student("e", 18);
List<Student> list = new ArrayList<>();
list.add(a);
list.add(b);
list.add(c);
list.add(d);
list.add(e);
在日常开发中,可能有以下的需求:
一、遍历该集合
list.forEach(System.out::println);
forEach接受一个Consumer表达式
二、取出学生姓名
List<String> nameList = list.stream()
.map(Student::getName)
.collect(Collectors.toList());
stream可以将一种形式的流转化为另外一种形式的流,上面的代码,是将包含整个学生对象的流,转化成了单独包含姓名的流,最后使用collect方法,将流收集起来。
三、取出年龄大于19岁的学生
List<Student> studentList = list.stream()
.filter(s -> s.getAge() > 19)
.collect(Collectors.toList());
filter接收一个Predicate表达式,将会在流中丢弃不符合表达式的学生对象。
四、取出不重复的学生年龄
List<Integer> ageDistinctList = list.stream()
.map(Student::getAge)
.distinct()
.collect(Collectors.toList());
和mysql的去重关键字一样,都是使用distinct
五、全匹配、任意匹配、都不匹配
需求1:是否所有学生的年龄都在18岁以上(全匹配)
boolean flag = list.stream()
.map(Student::getAge)
.allMatch(i -> i > 18);
需求2:是否有学生的年龄大于21岁(任意匹配)
boolean flag = list.stream()
.map(Student::getAge)
.anyMatch(i -> i > 21);
需求3:是否所有学生的年龄都不大于22岁(都不匹配)
boolean flag = list.stream()
.map(Student::getAge)
.noneMatch(i -> i > 22);
六、排序
需求,按照学生的年龄进行排序
list.stream()
.sorted(Comparator.comparingInt(Student::getAge))
.forEach(System.out::println);
输出:
默认是按照年龄进行升序输出,当然也可以降序输出,只要加上.reversed即可,如下图
list.stream()
.sorted(Comparator.comparingInt(Student::getAge).reversed())
.forEach(System.out::println);
如果先按照年龄排序,再按照姓名进行排序,则可以写成:
list.stream()
.sorted(Comparator.comparingInt(Student::getAge).thenComparing(Student::getName))
.forEach(System.out::println);
七、分页
需求:当前页是第2页,每页显示3条
list.stream()
.sorted(Comparator.comparingInt(Student::getAge))
.skip((2 - 1) * 3) //(当前页-1)*每页显示条数
.limit(3) //每页显示条数
.forEach(System.out::println);
首先按照年龄进行排序,然后跳过上一页的数据,取出之后的limit条数据。
八、分组
需求:照年龄进行分组
Map<Integer, List<Student>> group = list.stream().collect(Collectors.groupingBy(Student::getAge));
group.forEach((k, v) -> System.out.println("k:" + k + ",v:" + v.toString()));
输出:
九、字符串拼接
需求:输出学生姓名用逗号隔开的字符串
String str = list.stream().map(Student::getName).collect(Collectors.joining(","));
System.out.println(str);
输出:
十、数学运算
需求1:求学生年龄的总和
int sum = list.stream().mapToInt(Student::getAge).sum();
System.out.println(sum);
需求2:求学生年龄的平均数
double average = list.stream()
.mapToInt(Student::getAge)
.average()
.orElse(0.0);
System.out.println(average);
注意,average()返回的是一个OptionalDouble,为了防止集合中没有元素时,我们必须使用orElse指定一个默认值。
同理,求最大值使用max,最小值使用min,都需要指定默认值。
持续补充案例....