Stream 的使用

一、什么是 Stream?

  1. Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。

  2. 使用 Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式。

二、Stream 的特点

  1. stream 自己不会保存数据。
  2. 不会改变数据源,相反,他们会返回一个持有结构的新的 Stream。
  3. Stream 操作是延迟执行的,因此,它会等到需要结果时才执行。

三、Stream 的三个操作步骤

  1. 产生 Stream
    ① 通过 Collections 系列集合提供的 stream()方法或 parallelStream()获取
    ② 通过 Arrays 中的静态方法获取
    ③ 通过 Stream 类中的静态方法 of()获取
    ④ 创建无限流
    ⑤ ...

  2. 中间操作
    (1)筛选与切片:
      ① Stream<T> filter(Predicate predicate); // 过滤(返回值 boolean)
      ② Stream<T> limit(long maxSize); // 限制
      ③ Stream<T> skip(long n); // 跳过
      ④ Stream<T> distinct(); // 去重(比较 hash 值)
    (2)映射
      ① Stream<R> map(Function mapper); // 参数 lambda 表达式(有返回值)
      ② Stream<R> flatMap(Function mapper); // 参数 lambda 表达式(有返回值)
    (3)排序
      ① Stream<T> sorted() // 自然排序 Comparable
      ② Stream<T> sorted(Comparator comparator); // 定制排序
    (4)消费(与 map() 相似)
      ① Stream<T> peek(Consumer action); // 参数 lambda 表达式(无返回值)

  3. 终止操作(终端操作)
    (1)查找与匹配
      allMatch:检查是否匹配所有元素
      noneMatch:检查是否没匹配所有元素
      anyMatch:检查是否至少有一个元素匹配
      findFirst:返回流中第一个元素
      findAny:返回流中的任意元素
      count:返回流中元素的总个数
      max:返回流中元素最大值
      min:返回流中元素最小值
    (2)归约与收集
      ① Optional<T> reduce(BinaryOperator<T> accumulator)
      ② R collect(Collector collector);

四、Stream 演示

以下为全部代码,可直接运行
Person.java

package com.wl.model;

/**
 * @author  WL
 * @date : 2021年6月3日 08:27:19
 */
public class Person implements Comparable<Person> {
    private String name;
    private Integer age;
    private String gender;

    public Person() {
    }

    public Person(String name, Integer age, String gender) {
        super();
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + ", gender=" + gender + "]";
    }

    @Override
    public int compareTo(Person person) {
        return person.getAge() - this.age;
    }
}

StreamDemo.java

package com.wl.stream;

import com.wl.model.Person;

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

/**
 * @author  WL
 * @date : 2021年6月3日 08:27:19
 */
public class StreamDemo {
    public static Person person1 = new Person("Tom", 20, "男");
    public static Person person2 = new Person("Scott", 21, "女");
    public static Person person3 = new Person("John", 22, "男");
    public static Person person4 = new Person("Bob", 23, "女");

    public static List<Person> list = Arrays.asList(person1, person2, person3, person4, person4);

    public static void main(String[] args) {

        System.out.println("请输入要要演示的方法序号:");
        System.out.println("1.创建 Stream");
        System.out.println("2.中间操作--筛选与切片");
        System.out.println("3.中间操作--映射");
        System.out.println("4.中间操作--映射");
        System.out.println("5.中间操作--排序");
        System.out.println("6.查找与匹配");
        System.out.println("7.归约与收集");
        System.out.println("8.退出");
        System.out.println("请输入数字:(例:6)");
        while (true) {
            int num = new Scanner(System.in).nextInt();
            if (num == 1) {
                test1();
            } else if (num == 2) {
                test2();
            } else if (num == 3) {
                test3();
            } else if (num == 4) {
                test4();
            } else if (num == 5) {
                test5();
            } else if (num == 6) {
                test6();
            } else if (num == 7) {
                test7();
            } else if (num == 8) {
                break;
            } else {
                System.err.println("您输入的数字不正确,请重新输入:");
            }
        }
    }

    /**
     * 创建 Stream
     */
    public static void test1() {

        // 1. 通过 Collections 系列集合提供的 stream()方法或 parallelStream()获取
        List<String> list = Arrays.asList("aaa", "bbb", "ccc");

        list.forEach(System.out::println);
        // 2. 通过 Arrays 中的静态方法获取
        String[] strArr = {"aaa", "bbb", "ccc"};
        Stream<String> stream2 = Arrays.stream(strArr);

        // 3. 通过 Stream 类中的静态方法 of()获取
        Stream<String> stream3 = Stream.of("111", "222", "333");

        // 4. 创建无限流
        // 迭代
        Stream<Integer> stream4 = Stream.iterate(0, x -> x + 2);
        stream4.limit(20).forEach(System.out::println);

        // 生成
        Stream.generate(Math::random).limit(8).forEach(System.out::println);

    }

    /**
     * 中间操作--筛选与切片
     */
    public static void test2() {
        // distinct()比较 hash 值
        Stream<Person> stream = list.stream().filter(person -> person.getAge() > 20).distinct();

        // 终止,无终止,中间操作不执行
        stream.forEach(System.out::println);

    }

    /**
     * 中间操作--映射
     */
    public static void test3() {
        System.out.println("---------------------map----------------------------");
        Stream<Person> stream1 = list.stream().map(person -> {
            person.setAge(person.getAge() + 10);
            return person;
        });
        stream1.forEach(System.out::println);

        System.out.println("----------------------map----------------------------");
        Stream<String> strs = list.stream().map(Person::getName);
        strs.forEach(System.out::println);

        System.out.println("----------------------flatMap----------------------------");
        List<String> strList = Arrays.asList("a,b,c", "d,e", "f,g,h,i");

        // 把 {{a,b,c},{d,e},{f,g,h,i}} 流转化为 {a,b,c,d,e,f,g,h,i}
        Stream<String> stream2 = strList.stream().flatMap(s -> {
            String[] strArr = s.split(",");
            return Arrays.stream(strArr);
        });
        stream2.forEach(System.out::println);
    }

    /**
     * 中间操作--排序
     */
    public static void test4() {
        System.out.println("----------------------sorted Comparable----------------------------");
        // 使用 sorted(),Person 类需实现 Comparable 接口,重写 compareTo()方法
        /*
         *   @Override
         *    public int compareTo(Person person) {
         *       return person.getAge() - this.age;
         *   }
         */
        list.stream().sorted().forEach(System.out::println);

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

        System.out.println("----------------------age从大到小----------------------------");
        list.stream().sorted((p1, p2) -> p2.getAge() - p1.getAge()).forEach(System.out::println);

        System.out.println("----------------------age从小到大----------------------------");
        list.stream().sorted(Comparator.comparingInt(Person::getAge)).forEach(System.out::println);
    }

    /**
     * 中间操作--排序
     */
    public static void test5() {
        list.stream().peek(p -> p.setAge(25)).forEach(System.out::println);
    }

    /**
     * 查找与匹配
     */
    public static void test6() {
        System.out.println(list.stream().allMatch(x -> x.getGender().equals("男")));
        System.out.println(list.stream().noneMatch(x -> x.getGender().equals("男")));
        System.out.println(list.stream().anyMatch(x -> x.getGender().equals("男")));
        System.out.println(list.stream().findFirst().get());
        System.out.println(list.stream().findAny().get());
        System.out.println(list.stream().count());
        System.out.println(list.stream().max(Comparator.comparingInt(Person::getAge)).get());
        System.out.println(list.stream().min(Comparator.comparingInt(Person::getAge)).get());
    }

    /**
     * 归约与收集
     */
    public static void test7() {
        Integer ageSum = list.stream().map(Person::getAge).reduce(Integer::sum).get();
        System.out.println("年龄总和:" + ageSum);

        Set<String> nameSet = list.stream().map(Person::getName).collect(Collectors.toSet());
        System.out.println(nameSet);

        HashSet<String> nameHashSet = list.stream().map(Person::getName).collect(Collectors.toCollection(HashSet::new));
        System.out.println(nameHashSet);

        Double avgAge = list.stream().collect(Collectors.averagingDouble(Person::getAge));
        System.out.println("平均年龄:" + avgAge);
        Integer a = list.stream().mapToInt(Person::getAge).sum();
        System.err.println(a);

    }
}

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容