Java8中Stream的常用方法

前言

这篇文章简单总结一下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,都需要指定默认值。


持续补充案例....

猜你喜欢

转载自blog.csdn.net/qq_33591903/article/details/106645900