Stream:中间操作,终止行为

Stream

jdk8新增了Stream的新特性,可以对数据源中的数据进行运行或计算。

注:

  • 数组|集合可以作为存储数据的数据源,stream不能存储数据,只能对数据源中的数据进行计算,得到一个新的结果或一个新的stream
  • stream不会影响数据源中的数据
  • stream是一次性的,使用过一次以后不能再次使用
  • stream的特点是延迟加载,即进行一些操作时,如果没有终止行为,就不会执行中间操作,会在进行终止行为的时候统一执行

使用步骤:

  • 根据数据源获取流
  • 中间操作
  • 终止行为

本文所使用的类均为Student类,代码如下:

//定义Student类实现内部比较器
public class Student implements Comparable<Student>{
     
    private int id;
    private String name;
    private int age;

    public Student() {
     
    }

    public Student(int id, String name, int age) {
     
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public int getId() {
     
        return id;
    }

    public void setId(int id) {
     
        this.id = id;
    }

    public String getName() {
     
        return name;
    }

    public void setName(String name) {
     
        this.name = name;
    }

    public int getAge() {
     
        return age;
    }

    public void setAge(int age) {
     
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
     
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return id == student.id &&
                age == student.age &&
                Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
     
        return Objects.hash(id, name, age);
    }

    @Override
    public String toString() {
     
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    //重写compareTo方法
    @Override
    public int compareTo(Student o) {
     
        return this.getAge()-o.getAge();
    }
}

1. 中间操作

1.1 筛选与切片

  • filter():过滤信息
  • limit(n):取前n个
  • skip(n):跳过第n个
  • distinct():去重,按照重写Hashcode()与equals()方法判断相等去重

代码:

import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;
public class StreamDemo01 {
     
    public static void main(String[] args) {
     
        List<Student> list = List.of(
                new Student(101,"张三",19),
                new Student(102,"李四",17),
                new Student(103,"王五",25),
                new Student(104,"赵六",22),
                new Student(101,"张三",19));
        Stream<Student> stream1 = list.stream();
        //找到年龄大于17岁的学生
        stream1.filter(student -> {
     
            System.out.println("选取年龄>17岁的学生");
            return student.getAge()>17;
        }).forEach(System.out::println);
        Stream<Student> stream2 = list.stream();
        //找到年龄大于17岁的前三个学生
        stream2.filter(student -> {
     
            System.out.println("选取年龄>17岁的学生");
            return student.getAge()>17;
        }).limit(3).forEach(System.out::println);
        //找到年龄大于17岁的学生,跳过第一个
        Stream<Student> stream3 = list.stream();
        stream3.filter(student -> {
     
            System.out.println("选取年龄>17岁的学生");
            return student.getAge()>17;
        }).skip(1).forEach(System.out::println);
        //找到年龄大于17岁的学生,去重
        Stream<Student> stream4 = list.stream();
        stream4.filter(student -> {
     
            System.out.println("选取年龄>17岁的学生");
            return student.getAge()>17;
        }).distinct().forEach(System.out::println);
    }
}

1.2 排序

使用sorted()方法,默认使用内部比较器,如果想使用外部比较器需要定义。

代码:

public class StreamDemo02 {
     
    public static void main(String[] args) {
     
        List<Student> list = List.of(
                new Student(101,"张三",19),
                new Student(102,"李四",17),
                new Student(104,"王五",25),
                new Student(103,"赵六",22),
                new Student(101,"张三",19));
        //根据id做升序排序(使用外部比较器)
        Stream<Student> stream1 = list.stream();
        stream1.sorted((o1,o2)->o1.getId()-o2.getId()).forEach(System.out::println);
        //根据年龄做升序排序(使用内部比较器)
        Stream<Student> stream2 = list.stream();
        stream2.sorted().forEach(System.out::println);
    }
}

1.3 map方法与flatMap方法

  • map():把stream操作的每一个数据当作function接口中抽象的参数传递,根据指定的实现行为(lambda)得到一个结果,最终把所有的结果返回一个新的流。如果每一个结果都是一个流,最终会返回一个存放每一个流的新的流
  • flatMap():作用与map相等,特点是每一个数据必须返回一个流,最终会结合称为一个整个流

代码:

import java.util.List;
import java.util.stream.Stream;
public class StreamDemo03 {
     
    public static void main(String[] args) {
     
        List<Student> list = List.of(
                new Student(101,"张三",19),
                new Student(102,"李四",17),
                new Student(104,"王五",25),
                new Student(103,"赵六",22),
                new Student(101,"张三",19));
        //得到年龄数据
        Stream<Student> stream1 = list.stream();
        stream1.map(o->o.getAge()).forEach(System.out::println);
        //得到年龄数据
        Stream<Student> stream2 = list.stream();
        stream2.flatMap((s)->Stream.of(s.getAge())).forEach(System.out::println);
    }
}

2. 终止行为

2.1 reduce方法

reduce()方法有三种用法,具体通过代码展示:

import java.util.List;
import java.util.stream.Stream;
public class StreamDemo04 {
     
    public static void main(String[] args) {
     
        List<Student> list = List.of(
                new Student(101,"张三",19),
                new Student(102,"李四",17),
                new Student(104,"王五",25),
                new Student(103,"赵六",22),
                new Student(101,"张三",19));
        //获得数据中的年龄,将第一个年龄与第二个年龄相加,和作为第一个年龄继续加第二个年龄(此时第二个年龄为原来的第三个年龄),以此类推
        Stream<Student> stream1 = list.stream();
        int result1 = stream1.map(Student::getAge).sorted().reduce((x,y)->x+y).get();
        System.out.println(result1);//102
        //获得数据中的年龄,将100作为第一个参数,与第一个年龄相加,和作为第一个年龄继续加第二个年龄,剩下的操作与上面的相同
        Stream<Student> stream2 = list.stream();
        int result2 = stream2.map(Student::getAge).sorted().reduce(100,(x,y)-> {
     
            System.out.println(x+"-->"+y);
            return x+y;
        });
        System.out.println(result2);//202
        //获得数据中的年龄,将100与每一个年龄相加,求得的结果中第一个年龄与第二个年龄相加,剩下的操作与上面的相同
        //注:使用此用法时,流必须使用并行流
        Stream<Student> stream3 = list.parallelStream();
        int result3 = stream3.map(Student::getAge).sorted().reduce(100,(x,y)-> {
     
            System.out.println(x+"-->"+y);
            return x+y;
        },(x,y)->x+y);
        System.out.println(result3);//602
    }
}

2.2 查找与匹配

  • allMatch():检查是否匹配所有元素
  • anyMatch():检查是否至少匹配一个元素
  • noneMatch():检查是否没有匹配所有元素
  • findFirst():返回第一个元素
  • findAny():返回当前流中的任意元素
  • count():返回流中元素的总个数
  • max():返回流中最大值
  • min():返回流中最小值

代码:

import java.util.List;
import java.util.stream.Stream;
public class StreamDemo05 {
     
    public static void main(String[] args) {
     
        List<Student> list = List.of(
                new Student(101,"张三",19),
                new Student(102,"李四",17),
                new Student(104,"王五",25),
                new Student(103,"赵六",22),
                new Student(101,"张三",19));
        //allMatch():检查是否匹配所有元素
        Stream<Student> stream1 = list.stream();
        System.out.println(stream1.allMatch(o->o.getAge()>17));//false
        //anyMatch():检查是否至少匹配一个元素
        Stream<Student> stream2 = list.stream();
        System.out.println(stream2.anyMatch(o->o.getAge()==17));//true
        //noneMatch():检查是否没有匹配所有元素
        Stream<Student> stream3 = list.stream();
        System.out.println(stream3.noneMatch(o->o.getAge()<16));//true
        //findFirst():返回第一个元素
        Stream<Student> stream4 = list.stream();
        System.out.println(stream4.map(Student::getAge).sorted().findFirst().get());//17
        //findAny():返回当前流中的任意元素
        Stream<Student> stream5 = list.stream();
        System.out.println(stream5.map(Student::getAge).findAny().get());
        //count():返回流中元素的总个数
        Stream<Student> stream6 = list.stream();
        System.out.println(stream6.map(Student::getAge).count());//5
        //max():返回流中最大值
        Stream<Student> stream7 = list.stream();
        System.out.println(stream7.max((o1,o2)->o1.getAge()-o2.getAge()).map(Student::getAge).get());//25
        //min():返回流中最小值
        Stream<Student> stream8 = list.stream();
        System.out.println(stream8.min((o1,o2)->o1.getAge()-o2.getAge()).map(Student::getAge).get());//17
    }
}

2.3 收集

  • Collectors.toList():把流中所有元素收集到List中
  • Collectors.toSet():把流中所有元素收集到Set中,删除重复项
  • Collectors.toMap():把流中所有元素收集到Map中,当出现相同的key时会抛异常

代码:

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class StreamDemo06 {
     
    public static void main(String[] args) {
     
        List<Student> list = List.of(
                new Student(101,"张三",19),
                new Student(102,"李四",17),
                new Student(104,"王五",25),
                new Student(103,"赵六",22),
                new Student(101,"张三",19));
        //Collectors.toList():把流中所有元素收集到List中
        Stream<Student> stream1 = list.stream();
        List<Integer> list1 = stream1.map(Student::getAge).sorted().collect(Collectors.toList());
        list1.forEach(System.out::println);
        //Collectors.toSet():把流中所有元素收集到Set中,删除重复项
        Stream<Student> stream2 = list.stream();
        Set<Integer> set = stream2.map(Student::getAge).collect(Collectors.toSet());
        set.forEach(System.out::println);
        //Collectors.toMap():把流中所有元素收集到Map中,当出现相同的key时会抛异常
        Stream<Student> stream3 = list.stream();
        Map<String,Integer> map = stream3.distinct().collect(Collectors.toMap(Student::getName,Student::getAge));
        map.forEach((s,i)-> System.out.println(s+":"+i));
    }
}

你可能感兴趣的:(Java基础,stream,java)