Java jdk8新特性:Stream 流

一. Stream

  1. Stream也叫Stream流,是jdk8开始新增的一套API(java.util.stream.*),可以用于操作集合或者数组的数据。

  2. 优势:Stream流大量的结合了lambda的语言风格来编程,提供了一种更加强大,更加简洁的方式操作集合或者数组中的数据。

  3. 使用步骤:

① 获取Stream流

② Stream流常用的中间方法(支持链式调用)

③ Stream 流常见的终结方法

java 复制代码
 public static void main(String[] args) {
        //Stream
        List<String> list = new ArrayList<String>();
        Collections.addAll(list, "卡莎", "卡车", "泰坦", "璐璐", "卡拉", "卡卡卡", "伊泽");
        System.out.println(list);//[卡莎, 卡车, 泰坦, 璐璐, 卡拉, 卡卡卡, 伊泽]

        //list中方法 筛选数据
        List<String> list1 = new ArrayList<>();
        for(String str : list){
            if (str.contains("卡") && str.length() == 2){
                list1.add(str);
            }
        }
        System.out.println(list1);//[卡莎, 卡车, 卡拉]

        //使用stream流 筛选
        List<String> list2 = list.stream().filter(s -> s.contains("卡")).filter(s -> s.length() == 2).collect(Collectors.toList());
        System.out.println(list2);//v

}

二. Stream的常用方法

1. 获取Stream流

|------------------------|-----------------------------------------------------|------------------|
| | 方法 | 说明 |
| Collection提供的获取Stream流 | default Stream<E> stream() | 获取当前集合的Stream流 |
| Arrays类提供的获取Stream流 | public static <T> Stream<T> stream(T[] array) | 获取当前数组的Stream流 |
| Stream提供的获取Stream流 | public static<T> Stream<T> of(T... values) | 获取当前接收数据的Stream流 |

java 复制代码
public static void main(String[] args) {

        //1. 获取List集合的Stream流
        List<String> list = new ArrayList<String>();
        Collections.addAll(list, "卡莎", "卡车", "泰坦", "璐璐", "卡拉", "卡卡卡", "伊泽");
        //获取Stream流
        Stream<String> stream = list.stream();

        //2. 获取Set集合的Stream流
        Set<String> set = new HashSet<String>();
        Collections.addAll(set, "大宇", "朵朵", "欢欢", "麦琪");
        //获取Stream流
        Stream<String> stream1 = set.stream();
        stream1.filter(s -> s.contains("欢")).forEach(System.out::println);

        //3. 获取Map集合的Stream流
        Map<String, String> map = new HashMap<>();
        map.put("杨过", "小龙女");
        map.put("张无忌", "赵敏");
        map.put("郭靖", "黄蓉");
        map.put("令狐冲", "东方不败");
        // 获取Stream流 分开处理
        Set set2 = map.entrySet();
        Stream<String> keys = set2.stream();
        Collection<String> values = map.values();
        Stream<String> vas = values.stream();

        //统一处理
        Set<Map.Entry<String, String>> entry = map.entrySet();
        Stream<Map.Entry<String, String>> kvs = entry.stream();
        kvs.filter(k -> k.getKey().contains("张")).forEach(System.out::println);


        //4. 获取数组的Stream流
        String[] str = {"路马", "天天", "莱德", "落落"};
        //public static <T> Stream<T> stream(T[] array)
        Stream<String> stream2 = Arrays.stream(str);
        //public static<T> Stream<T> of(T... values)
        Stream<String> stream3 = Stream.of(str);    
}

2. Stream流常见的中间方法

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

|------------------------------------------------------------------|------------------|
| 常用方法 | 说明 |
| Stream<T> filter(Predicate<? super T> predicate) | 用于对流中的数据进行过滤 |
| Stream<T> sorted() | 对元素进行升序排序 |
| Stream<T> sorted(Comparator<? super T> comparator) | 对元素按照指定规则排序 |
| Stream<T> limit(long maxSize) | 获取前几个元素 |
| Stream<T> skip(long n) | 跳过前几个元素 |
| Stream<T> distinct() | 去除流中重复的元素 |
| <R> Stream<R> map(Function<? super T, ? extends R> mapper) | 对元素进行加工,并返回对应的新流 |
| static <T> Stream<T> concat(Stream a, Stream b) | 合并a和b两个流 |

java 复制代码
public class Student{
    private String name;
    private int age;
    private double score;

    public Student() {
    }

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

    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 getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }

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

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

    @Override
    public int hashCode() {
        return Objects.hash(name, age, score);
    }
}
java 复制代码
public static void main(String[] args) {
        List<Double> scores = new ArrayList<Double>();
        Collections.addAll(scores, 99.0, 96.0, 94.0,59.0, 66.0, 74.0);
        //成绩大于等于60的并排序
        scores.stream().filter(s -> s >= 60.0).sorted().forEach(System.out::println);//66.0 74.0 94.0 96.0 99.0
        System.out.println("--------------------------------------------");

        List<Student> students = new ArrayList<>();
        Student s1 = new Student("卡莎", 18, 99.0);
        Student s2 = new Student("泰坦", 19, 93.0);
        Student s3 = new Student("伊泽", 16, 98.0);
        Student s4 = new Student("璐璐", 14, 96.0);
        Student s5 = new Student("璐璐", 14, 96.0);
        Collections.addAll(students, s1, s2, s3, s4, s5);

        //找出年龄大于等于16 且小于等于20 按照年龄降序
        //filter() sorted()
        students.stream().filter(s -> s.getAge() >= 16 && s.getAge() <= 20).sorted(((o1, o2) -> o2.getAge() - o1.getAge()))
                .forEach(System.out::println);
        System.out.println("--------------------------------------------");

        //找出分数最高的前三名
        // sorted() limit()
        students.stream().sorted((o1, o2) -> Double.compare(o2.getScore(), o1.getScore())).limit(3).forEach(System.out::println);
        System.out.println("--------------------------------------------");

        //找出分数最低的 倒数3名
        //sorted() skip()
        students.stream().sorted((o1, o2) -> Double.compare(o2.getScore(), o1.getScore())).skip(students.size() - 3).forEach(System.out::println);
        System.out.println("--------------------------------------------");

        //成绩大于等于95的 去除重复的名字
        // distinct() 自定义类型 如果希望内容一样认为重复 需重写 equals()和 hashCode()
        //filter() map()  distinct()
        students.stream().filter(s -> s.getScore() >= 95).map(s -> s.getName()).distinct().forEach(System.out::println);

        students.stream().filter(s -> s.getScore() >= 95).distinct().forEach(System.out::println);

        //static <T> Stream<T> concat(Stream a, Stream b)	合并a和b两个流
        Stream<String> stream = Stream.of("1", "2", "3");
        Stream<String> stream2 = Stream.of("4", "5", "6", "7", "8", "9");
        Stream<String> stream3 = Stream.concat(stream, stream2);
        stream3.forEach(System.out::println);

}

3. Stream流常见的终结方法

(1) 终结方法指的是调用完成后,不会再返回新的Stream流了,不能再继续使用Stream流了。

|-------------------------------------------------------|---------------|
| 方法名称 | 说明 |
| void forEach(Consumer action) | 对此流运算后的元素进行遍历 |
| long count() | 统计此流运算后的元素个数 |
| Optional<T> max(Comparator<? super T> copmarator) | 获取此流运算后的最大值元素 |
| Optional<T> min(Comparator<? super T> copmarator) | 获取此流运算后的最小值元素 |

|--------------------------------|--------------------|
| 方法名称 | 说明 |
| R collect(Collector collector) | 把流处理后的结果放到一个指定的集合中 |
| Object[] toArray() | 把流处理后的结果放到一个指定的数组中 |

java 复制代码
public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        Student s1 = new Student("卡莎", 18, 99.0);
        Student s2 = new Student("泰坦", 19, 93.0);
        Student s3 = new Student("伊泽", 16, 98.0);
        Student s4 = new Student("璐璐", 14, 96.0);
        Student s5 = new Student("璐璐", 14, 96.0);
        Collections.addAll(students, s1, s2, s3, s4, s5);

        // 计算分数超过95的有几个 .count()
        long l = students.stream().filter(s -> s.getScore() > 95).count();
        System.out.println(l);//4

        //找出分数最高的 并输出 .max()
        Student smax = students.stream().max((o1, o2) -> Double.compare(o1.getScore(), o2.getScore())).get();
        System.out.println(smax);

        //找出分数最低的 并输出 .min()
        Student smin = students.stream().min((o1, o2) -> Double.compare(o1.getScore(), o2.getScore())).get();
        System.out.println(smin);

        //计算分数超过95的 并放到一个新集合中
        //流只能收集一次

        List<Student> list1 = students.stream().filter(s -> s.getScore() > 95).collect(Collectors.toList());
        System.out.println(list1);

        Set<Student> list2 = students.stream().filter(s -> s.getScore() > 95).collect(Collectors.toSet());
        System.out.println(list2);

        //找出分数超过95的 并把名字和分数放到一个map集合中
        //不会自动去重 需调用distinct()去重
        Map<String, Double> map = students.stream().filter(s -> s.getScore() > 95).distinct().collect(Collectors.toMap(m -> m.getName(), m -> m.getScore()));
        System.out.println(map);


        //找出分数超过95的 并把名字和分数放到一个数组
        Object[] arr = students.stream().filter(s -> s.getScore() > 95).toArray();
        Student[] arr1 = students.stream().filter(s -> s.getScore() > 95).toArray(len -> new Student[len]);
        System.out.println(Arrays.toString(arr));
        System.out.println(Arrays.toString(arr1));
}
相关推荐
m0_74823507几秒前
使用rustDesk搭建私有远程桌面
java
Source.Liu几秒前
【学Rust开发CAD】1 环境搭建
开发语言·rust
快乐是7 分钟前
发票打印更方便
java
文浩(楠搏万)11 分钟前
Java内存管理:不可达对象分析与内存泄漏优化技巧 Eclipse Memory Analyzer
java·开发语言·缓存·eclipse·内存泄漏·不可达对象·对象分析
圆蛤镇程序猿13 分钟前
【什么是MVCC?】
java·数据库·oracle
m0_7482567814 分钟前
【SQL】掌握SQL查询技巧:数据分组与排序
java·jvm·sql
绛洞花主敏明15 分钟前
我的nvim的init.lua配置
开发语言·junit·lua
Damon撇嘴笑16 分钟前
Cause: java.sql.SQLException: sql injection violation, comment not allow异常问题处理
java·数据库·sql
孟秋与你26 分钟前
【redisson】redisson分布式锁原理分析
java·分布式
自律小仔1 小时前
Go语言的 的继承(Inheritance)核心知识
开发语言·后端·golang