Stream的中间操作API

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ycd500756/article/details/82534934

定义

流中的中间操作可以连接起来形成一个流水线,如果该流水线没有触发终止操作,那么中间操作是不会执行任何的处理的。只是会在终止条件中一次性全部执行,这个过程称为“惰性求值”。具体怎么理解,下面演示一个demo。首先有个概念stream中有个filter()为中间操作,也有一个方法forEach()属于终止操作。

demo的数据准备
编写一个实体类,主要用于创建对象然后放到集合中。Studen类中三个重写方法不一定需要覆盖的。

package com.mark.java8.entity;
public class Student {
    String name ; //姓名
    Integer age; //年龄

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
    /**
    *以下省略的get()和set()
    **/
}

接下来看看测试类

public class StreamAPITest1 {
    private List<Student> studentList = Arrays.asList(
            new Student("Mark",23),
            new Student("Eason",45),
            new Student("Abel",18),
            new Student("Jay",32),
            new Student("Jack",50),
            new Student("Jack",50));


    //1.测试过滤API:filter()
    @Test
    public void testFilter() {
        //1.获取流
        //2.进行中间操作的filter方法
        Stream<Student> studentStream = studentList.stream().filter((student)->{
            System.out.println("中间操作"+student);
            return student.getAge() > 18;
        });
    }
}

运行结果:并没有任何的输入语句,也就是filte方法中的输出语句没有执行到。因为测试方法中没有定义终止操作。接下来添加上终止的方法forEach()


    //1.测试过滤API:filter()
    @Test
    public void testFilter() {
        //1.获取流
        //2.进行中间操作的filter方法
        Stream<Student> studentStream = studentList.stream().filter((student)->{
            System.out.println("中间操作"+student);
            return student.getAge() > 18;
        });
        //3.终止操作
        studentStream.forEach(System.out::println);//使用内部迭代
    }

运行结果:

中间操作Student{name=’Mark’, age=23}
Student{name=’Mark’, age=23}
中间操作Student{name=’Eason’, age=45}
Student{name=’Eason’, age=45}
中间操作Student{name=’Abel’, age=18}
中间操作Student{name=’Jay’, age=32}
Student{name=’Jay’, age=32}
中间操作Student{name=’Jack’, age=50}
Student{name=’Jack’, age=50}
中间操作Student{name=’Jack’, age=50}
Student{name=’Jack’, age=50}


2:中间操作

2.1:过滤操作:filter()

过滤操作的demo如上所示


2.2:限制操作:limit()

    @Test
    public void testLimit(){
        studentList.stream()
                .filter((student)->{//过滤操作返回年龄大于18的学生
                    System.out.println("filter--->"+student);
                    return student.getAge() > 18;
                })
                .limit(2)//中间操作限制返回2条结果
                .forEach(System.out::println);//终止操作
    }

输出结果:

filter—>Student{name=’Mark’, age=23}
Student{name=’Mark’, age=23}
filter—>Student{name=’Eason’, age=45}
Student{name=’Eason’, age=45}

总结:中间操作可以链式调用,limit()方法具有短路的属性,即找到满足条件后就不会继续往下执行了;如上面demo中的,找到两条满足条件的条件后就会继续往下执行了。


2.3:中间操作:跳过n个指定的元素:skip()

    @Test
    public void testSkip(){
        studentList.stream().filter((student)->{
                    System.out.println("filter--->"+student);
                    return student.getAge() > 18;
                }).skip(2)
                .forEach(System.out::println);
    }

运行结果:

filter—>Student{name=’Mark’, age=23}
filter—>Student{name=’Eason’, age=45}
filter—>Student{name=’Abel’, age=18}
filter—>Student{name=’Jay’, age=32}
Student{name=’Jay’, age=32}
filter—>Student{name=’Jack’, age=50}
Student{name=’Jack’, age=50}
filter—>Student{name=’Jack’, age=50}
Student{name=’Jack’, age=50}

运行结果分析:
学生Mark和Eason会被跳过,导致不会在终止操作中打印输出,
学生Abel不满足过滤条件大于18岁,导致不会在终止操作中打印输出,
剩下的几位运气不错都满足了过滤条件,所以他们都在终止操作中打印输出了。

总结:
skip()会返回的结果跳过指定的前n个元素,如果流中的元素不足n个,则返回的是一个空的流。


2.4:中间操作:筛选:skip()

该终止操作会过生成元素的hashCode()和equals()方法去除重复的元素

public void testDistinct(){
        List<Student> studentList = Arrays.asList(
                new Student("Mark",23),
                new Student("Jack",50),//定义两个属性相同的对象
                new Student("Jack",50));
        studentList.stream().filter((student)->{//获取流然后执行中间操作过滤
            System.out.println("filter--->"+student);
            return student.getAge() > 18;
        }).distinct() //通过筛选去除重复的元素
          .forEach(System.out::println);//终止操作
    }

运行结果:

filter—>Student{name=’Mark’, age=23}
Student{name=’Mark’, age=23}
filter—>Student{name=’Jack’, age=50}
Student{name=’Jack’, age=50}
filter—>Student{name=’Jack’, age=50}

运行结果分析:从打印语句中可以看出在终止操作中只是输出了一条学生Jack,注意(在学生Student实体类中我已经重写hashCode 和 equals 方法)

猜你喜欢

转载自blog.csdn.net/ycd500756/article/details/82534934