10_Stream

Stream

认识 Stream 流

首先我们需要有一个数据源,然后才能获取 Stream 流,它代表一条流水线,并能与数据源建立连接,然后我们能够通过这条流水线的各个方法对数据进行处理、计算。

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public class Test {
    public static void main(String[] args) {
        List<String> lst = new ArrayList<>();
        Collections.addAll(lst, "java1", "Java2", "Java3", "java4", "JAVA5");
        System.out.println(lst);  // [java1, Java2, Java3, java4, JAVA5]

        // 使用普通for循环的方式解决
        List<String> lst2 = new ArrayList<>();
        for (String s : lst) {
            if (s.startsWith("Java") && s.length() >= 4) {
                lst2.add(s);
            }
        }
        System.out.println(lst2);  // [Java2, Java3]

        // 使用 Stream 流来解决这个问题
        List<String> lst3 = lst.stream().filter(s -> s.startsWith("Java"))
                .filter(s -> s.length() >= 4).collect(Collectors.toList());

        System.out.println(lst3);  // [Java2, Java3]

    }
}
获取 Stream 流
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Test {
    public static void main(String[] args) {
        // 1. 如何获取List集合的Stream流?
        List<String> lst = new ArrayList<>();
        Collections.addAll(lst, "Java1", "Java2", "java3", "java4");
        Stream<String> stream1 = lst.stream();

        // 2. 如何获取Set集合的Stream流
        Set<String> set = new HashSet<>();
        Collections.addAll(set, "java1", "java2", "Java3", "Java4");
        Stream<String> stream2 = set.stream();
        stream2.filter(s -> s.contains("Java")).forEach(s -> System.out.println(s));  // Java3  Java4

        // 3. 如何获取Map集合的Stream流
        Map<String, Double> map = new HashMap<>();
        map.put("java1", 8.5);
        map.put("java2", 9.3);
        map.put("java3", 7.2);
        map.put("python1", 7.4);
        map.put("python2", 9.6);

        // 获取键的 Stream 流
        Set<String> keys = map.keySet();
        Stream<String> ks = keys.stream();

        // 获取值的 Stream 流
        Collection<Double> values = map.values();
        Stream<Double> vs = values.stream();

        // 获取"键值对"整体的 Stream 流
        Set<Map.Entry<String, Double>> entries = map.entrySet();
        Stream<Map.Entry<String, Double>> kvs = entries.stream();
        kvs.filter(e -> e.getKey().contains("j"))
                .filter(e -> e.getValue() > 8.5).forEach(s -> System.out.println(s));  // java2=9.3

        // 4. 如何获取数组的Stream流
        String[] arr = {"Java1", "Java2", "java3", "java4"};
//      Stream<String> stream = Arrays.stream(arr);  // 方法一
        Stream<String> stream = Stream.of(arr);  // 方法二
    }
}
Stream 流的中间方法
import java.util.*;
import java.util.stream.Stream;

public class Test {
    public static void main(String[] args) {
        List<Double> scores = new ArrayList<>();
        Collections.addAll(scores, 88.5, 100.0, 60.0, 99.0, 9.5, 99.5, 25.0);
        // 需求1. 找出成绩大于等于60分的数据,并升序后,再输出
        // sorted():升序
        scores.stream().filter(s -> s >= 60).sorted().forEach(e -> System.out.println(e));
        System.out.println("-----------------------------");


        // 准备一些对象
        List<Student> lst = new ArrayList<>();
        Student s1 = new Student("Jack", 26, 96.8);
        Student s2 = new Student("Peter", 19, 48.2);
        Student s3 = new Student("Tony", 33, 52.7);
        Student s4 = new Student("Tomato", 28, 99.4);
        Student s5 = new Student("Tomato", 28, 99.4);
        Collections.addAll(lst, s1, s2, s3, s4, s5);

        // 需求2. 找出年龄大于等于23,且年龄小于等于30岁的学生,并按照年龄降序输出
        // sorted() + lambda表达式实现自定义排序
        lst.stream().filter(s -> s.getAge() >= 23).filter(e -> e.getAge() <= 30)
                .sorted((o1, o2) -> o2.getAge() - o1.getAge()).forEach(k -> System.out.println(k));
        System.out.println("-----------------------------");


        // 需求3. 取出身高最高的前3名学生,并输出
        // limit():取前面几个
        lst.stream().sorted((o1, o2) -> Double.compare(o2.getHeight(), o1.getHeight()))
                .limit(3).forEach(s -> System.out.println(s));
        System.out.println("-----------------------------");


        // 需求4. 取出身高倒数的2名学生,并输出
        // skip():跳过前面多少个
        lst.stream().sorted((o1, o2) -> Double.compare(o2.getHeight(), o1.getHeight()))
                .skip(lst.size() - 2).forEach(System.out::println);  // System.out::println 的本质就是 s -> System.out.println(s)
        System.out.println("-----------------------------");


        // 需求5. 找出身高超过98的学生叫什么名字,要求去除重复的名字,再输出
        // map():映射,本例中map()将对象映射成对象的名字
        // distinct():去除重复的
        lst.stream().filter(s -> s.getHeight() > 98).map(s -> s.getName())
                .distinct().forEach(s -> System.out.println(s));
        System.out.println("-----------------------------");

        // distinct()去除重复,但是对于自定义的对象,如果希望对象内容一样就认为是重复,需要重写hashCode与equals方法
        lst.stream().filter(s -> s.getHeight() > 98).distinct().forEach(s -> System.out.println(s));
        System.out.println("-----------------------------");


        // 需求6. 合并 Stream 流
        Stream<String> stream1 = Stream.of("Jack", "Peter");
        Stream<String> stream2 = Stream.of("Jack2", "Peter2", "Tomato");
        Stream<String> stream3 = Stream.concat(stream1, stream2);
        stream3.forEach(System.out::println);  // 本质就是 stream3.forEach(s -> System.out.println(s))

    }
}

class Student {
    private String name;
    private int age;
    private double height;

    // 重写 hashCode 与 equals 方法


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

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

    public Student() {

    }

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", height=" + height +
                '}';
    }

    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;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }
}
Stream 流的终结方法
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Test {
    public static void main(String[] args) {
        // 准备一些对象
        List<Student> lst = new ArrayList<>();
        Student s1 = new Student("Jack", 26, 96.8);
        Student s2 = new Student("Peter", 19, 48.2);
        Student s3 = new Student("Tony", 33, 52.7);
        Student s4 = new Student("Tomato", 28, 99.4);
        Student s5 = new Student("Tomato", 28, 99.4);
        Collections.addAll(lst, s1, s2, s3, s4, s5);

        // 需求1. 请计算出身高超过98的学生人数
        // count():计算
        long num = lst.stream().filter(s -> s.getHeight() > 98).count();
        System.out.println(num);
        System.out.println("-----------------------------");


        // 需求2. 请找出身高最高的学生对象,并输出
        // max():取最大,如果是自定义对象,请重写并使用 lambda 表达式
        // get():获取当前 Stream 流的内容
        Student obj1 = lst.stream().max((o1, o2) -> Double.compare(o1.getHeight(), o2.getHeight())).get();
        System.out.println(obj1);
        System.out.println("-----------------------------");


        // 需求3. 请找出身高最矮的学生对象,并输出
        // skip():跳过前面多少个
        Student obj2 = lst.stream().min((o1, o2) -> Double.compare(o1.getHeight(), o2.getHeight())).get();
        System.out.println(obj2);
        System.out.println("-----------------------------");

        // 收集 Stream 流:就是把 Stream 流操作后的结果转回到集合或者数组中
        // 需求4. 请找出身高超过98的学生对象,并放到一个新集合中去返回
        List<Student> lst2 = lst.stream().filter(a -> a.getHeight() > 98).collect(Collectors.toList());
        System.out.println(lst2);

        Set<Student> set = lst.stream().filter(a -> a.getHeight() > 98).collect(Collectors.toSet());
        System.out.println(set);
        System.out.println("-----------------------------");

        // 需求5. 请找出身高超过170的学生对象,并把学生对象的名字和身高,存入到一个Map集合返回
        Map<String, Double> map = lst.stream().filter(k -> k.getHeight() > 98)
                .distinct().collect(Collectors.toMap(k -> k.getName(), k -> k.getHeight()));
        // 上面的做法是:使用对象的名字作为key,对象的身高作为value,所有名字重复的对象,一定要用distinct()剔除,不然报错
        System.out.println(map);

//      Object[] arr = lst.stream().filter(k -> k.getHeight() > 98).toArray();
        Student[] arr = lst.stream()
                .filter(k -> k.getHeight() > 98).toArray(Student[]::new);  // e -> new Student[e]
        System.out.println(arr[0]);

    }
}

class Student {
    private String name;
    private int age;
    private double height;

    // 重写 hashCode 与 equals 方法


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

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

    public Student() {

    }

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", height=" + height +
                '}';
    }

    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;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值