一、认识stream流

1.1、介绍

stream流是jdk8开始新增的一套API(java.util.stream.*),可以用于操作集合或者数组的数据。
stream流可以看做一条流水线,先将数据读入stream流,在stream流上可以对数据进行一系列处理

1.2、优势

Stream流大量的结合了Lambda的语法风格来编程,功能强大,性能高效,代码简洁,可读性好。

1.3、示例

目标:认识Stream流,掌握其基本使用步骤。体会它的优势和特点。

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

public class StreamDemo1 {
    public static void main(String[] args) {

        List<String> list = new ArrayList<>();
        list.add("张无忌");
        list.add("周芷若");
        list.add("赵敏");
        list.add("张强");
        list.add("张三丰");
        list.add("张翠山");

        // 1、先用传统方案:找出姓张的人,名字为3个字的,存入到一个新集合中去。
        List<String> newList = new ArrayList<>();
        for (String name : list) {
            if(name.startsWith("张") && name.length() == 3){
                newList.add(name);
            }
        }
        System.out.println(newList);

        // 2、使用Stream流解决
        List<String> newList2 = list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).collect(Collectors.toList());
        System.out.println(newList2);
    }
}

二、使用步骤

stream流可以对单列集合,双列集合,数组,零散数据进行一系列处理,过滤,收集,最后得到想要的结果

2.1、获取Stream流

2.1.1、说明

2.1.2、使用

目标:获取Stream流的方式。

import java.util.*;
import java.util.stream.Stream;

public class StreamDemo2 {
    public static void main(String[] args) {
 
        // 1、获取集合的Stream流:调用集合提供的stream()方法
        Collection<String> list = new ArrayList<>();
        Stream<String> s1 = list.stream();

        // 2、Map集合,怎么拿Stream流。
        Map<String, Integer> map = new HashMap<>();
        // 获取键流
        Stream<String> s2 = map.keySet().stream();
        // 获取值流
        Stream<Integer> s3 = map.values().stream();
        // 获取键值对流
        Stream<Map.Entry<String, Integer>> s4 = map.entrySet().stream();

        // 3、获取数组的流。
        String[] names = {"张三丰", "张无忌", "张翠山", "张良", "张学友"};
        Stream<String> s5 = Arrays.stream(names);
        System.out.println(s5.count()); // 5
        Stream<String> s6 = Stream.of(names);
        Stream<String> s7 = Stream.of("张三丰", "张无忌", "张翠山", "张良", "张学友");
    }
}

2.2、调用流水线的各种方法(中间方法)

2.2.1、介绍

中间方法指的是调用完成后会返回新的Stream流,可以继续使用(支持链式编程)

2.2.2、使用

目标:掌握Stream提供的常用的中间方法,对流上的数据进行处理(返回新流:支持链式编程)

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class StreamDemo3 {
    public static void main(String[] args) {
        
        List<String> list = new ArrayList<>();
        list.add("张无忌");
        list.add("周芷若");
        list.add("赵敏");
        list.add("张强");
        list.add("张三丰");
        list.add("张翠山");

        // 1、过滤方法
        list.stream().filter(s -> s.startsWith("张") &&  s.length() == 3).forEach(System.out::println);

        // 2、排序方法。
        List<Double> scores = new ArrayList<>();
        scores.add(88.6);
        scores.add(66.6);
        scores.add(66.6);
        scores.add(77.6);
        scores.add(77.6);
        scores.add(99.6);
        scores.stream().sorted().forEach(System.out::println); // 默认是升序。
        System.out.println("--------------------------------------------------");

        scores.stream().sorted((s1, s2) -> Double.compare(s2, s1)).forEach(System.out::println); // 降序
        System.out.println("--------------------------------------------------");

        scores.stream().sorted((s1, s2) -> Double.compare(s2, s1)).limit(2).forEach(System.out::println); // 只要前2名
        System.out.println("--------------------------------------------------");

        scores.stream().sorted((s1, s2) -> Double.compare(s2, s1)).skip(2).forEach(System.out::println); // 跳过前2名
        System.out.println("--------------------------------------------------");

        // 如果希望自定义对象能够去重复,重写对象的hashCode和equals方法,才可以去重复!
        scores.stream().sorted((s1, s2) -> Double.compare(s2, s1)).distinct().forEach(System.out::println); // 去重复

        // 映射/加工方法: 把流上原来的数据拿出来变成新数据又放到流上去。
        scores.stream().map(s -> "加10分后:" + (s + 10)).forEach(System.out::println);

        // 合并流:
        Stream<String> s1 = Stream.of("张三丰", "张无忌", "张翠山", "张良", "张学友");
        Stream<Integer> s2 = Stream.of(111, 22, 33, 44);
        Stream<Object> s3  = Stream.concat(s1, s2);
        System.out.println(s3.count());
    }
}

2.3、获取处理后的结果(终结方法)

2.3.1、介绍

1、终结方法

调用完成后,不会返回新Stream了,没法继续使用流了。

2、收集Stream流

就是把Stream流操作后的结果转回到集合或者数组中去返回。

2.3.2、使用

目标:掌握Stream流的统计,收集操作(终结方法)

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class StreamDemo4 {
    public static void main(String[] args) {
        
        List<Teacher> teachers = new ArrayList<>();
        teachers.add(new Teacher("张三", 23, 5000));
        teachers.add(new Teacher("金毛狮王", 54, 16000));
        teachers.add(new Teacher("李四", 24, 6000));
        teachers.add(new Teacher("王五", 25, 7000));
        teachers.add(new Teacher("白眉鹰王", 66, 108000));
        teachers.add(new Teacher("陈昆", 42, 48000));

        teachers.stream().filter(t -> t.getSalary() > 15000).forEach(System.out::println);

        System.out.println("--------------------------------------------------");

        long count = teachers.stream().filter(t -> t.getSalary() > 15000).count();
        System.out.println(count);

        System.out.println("--------------------------------------------------");

        // 获取薪水最高的老师对象
        Optional<Teacher> max = teachers.stream().max((t1, t2) -> Double.compare(t1.getSalary(), t2.getSalary()));
        Teacher maxTeacher = max.get(); // 获取Optional对象中的元素
        System.out.println(maxTeacher);

        Optional<Teacher> min = teachers.stream().min((t1, t2) -> Double.compare(t1.getSalary(), t2.getSalary()));
        Teacher minTeacher = min.get(); // 获取Optional对象中的元素
        System.out.println(minTeacher);

        System.out.println("---------------------------------------------------------");

        List<String> list = new ArrayList<>();
        list.add("张无忌");
        list.add("周芷若");
        list.add("赵敏");
        list.add("张强");
        list.add("张三丰");
        list.add("张三丰");
        list.add("张翠山");

        // 流只能收集一次

        // 收集到集合或者数组中去。
        Stream<String> s1 = list.stream().filter(s -> s.startsWith("张"));
        // 收集到List集合
        List<String> list1 = s1.collect(Collectors.toList());
        System.out.println(list1);

//        Set<String> set2 = new HashSet<>();
//        set2.addAll(list1);

        // 收集到Set集合
        Stream<String> s2 = list.stream().filter(s -> s.startsWith("张"));
        Set<String> set = s2.collect(Collectors.toSet());
        System.out.println(set);

        // 收集到数组中去
        Stream<String> s3 = list.stream().filter(s -> s.startsWith("张"));
        Object[] array = s3.toArray();
        System.out.println("数组:" + Arrays.toString(array));

        System.out.println("------------------收集到Map集合---------------------------");

        // 收集到Map集合:键是老师名称,值是老师薪水
        Map<String, Double> map = teachers.stream().collect(Collectors.toMap(Teacher::getName, Teacher::getSalary));
        System.out.println(map);
    }
}
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

// 1、对象类实现一个Comparable比较接口,重写compareTo方法,指定大小比较规则
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Teacher implements Comparable<Teacher>{
   private String name;
   private int age;
   private double salary;

   @Override
   public String toString() {
       return "Teacher{" +
               "name='" + name + '\'' +
               ", age=" + age +
               ", salary=" + salary +
               '}' + "\n";
   }

    // t2.compareTo(t1)
    // t2 == this 比较者
    // t1 == o  被比较者
    // 规定1:如果你认为左边大于右边 请返回正整数
    // 规定2:如果你认为左边小于右边 请返回负整数
    // 规定3:如果你认为左边等于右边 请返回0
    // 默认就会升序。
   @Override
   public int compareTo(Teacher o) {
       // 按照年龄升序
//        if(this.getAge() > o.getAge()) return 1;
//        if(this.getAge() < o.getAge()) return -1;
//        return 0;
       return this.getAge() - o.getAge(); // 升序
//        return o.getAge() - this.getAge(); // 降序
   }
}

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐