Java8——Stream流

亦凉 2021-09-18 05:36 538阅读 0赞

Stream是数据渠道,用于操作集合、数组等生成的元素序列。

Stream操作的三个步骤:

  • 创建Stream
  • 中间操作
  • 终止操作

一、获取stream的四种方式

  1. 通过collection系列集合的stream()parallelStream()获取。

    @Test
    void test11(){

    1. List<String> list = new ArrayList<>();
    2. Stream<String> stringStream = list.stream();

    }

  2. 通过Arrays中的静态方法stream()获取数组流。

    @Test
    void test11(){

    1. Person[] person = new Person[10];
    2. Arrays.stream(person);

    }

  3. 通过Stream中的静态方法of()

    @Test
    void test11(){

    1. Stream<String> stream = Stream.of("a", "b", "c");

    }

  4. 创建无限流

    /* 迭代 */
    @Test
    void test11(){

    1. Stream<Integer> integerStream = Stream.iterate(0, x -> x + 2);

    }

    /* 生成 */
    @Test
    void test11(){

    1. Stream.generate(() -> Math.random());

    }

二、中间操作

中间操作不会执行任何操作,只有终止操作才会一次性输出全部值,即“惰性求值”。

2.1 筛选与切片

  • filter——接收lamdba,从流中排除某些元素

    @Test
    void test12(){

    1. List<Person> personList = Arrays.asList(
    2. new Person("Java旅途",18),
    3. new Person("Java旅途",20)
    4. );
    5. // 中间操作
    6. Stream<Person> personStream = personList.stream()
    7. .filter(e -> e.getAge() > 18);
    8. // 终止操作
    9. personStream.forEach(System.out::println);

    }

  • limit——截断流,使其元素不超过给定数量

    @Test
    void test12(){

    1. List<Person> personList = Arrays.asList(
    2. new Person("Java旅途",18),
    3. new Person("Java旅途",20)
    4. );
    5. personList.stream()
    6. .limit(1)
    7. .forEach(System.out::println);

    }

  • skip(n)——跳过元素,返回一个扔掉前n个元素的流,若不足n个,则返回一个空流。与limit(n)互补。

    @Test
    void test12(){

    1. List<Person> personList = Arrays.asList(
    2. new Person("Java旅途",18),
    3. new Person("Java旅途",20)
    4. );
    5. personList.stream()
    6. .skip(1)
    7. .forEach(System.out::println);

    }

  • distinct——筛选,通过生成元素的hashCode()equals(),去除重复元素。

    @Test
    void test12(){

    1. List<Person> personList = Arrays.asList(
    2. new Person("Java旅途",18),
    3. new Person("Java旅途",20),
    4. new Person("Java旅途",20)
    5. );
    6. personList.stream()
    7. .distinct()
    8. .forEach(System.out::println);

    }

注意:使用distinct的时候需要重写实体的hashCode()equals()方法。

2.2 映射

  • map——接收lamdba,将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。

    /* 获取personList的所有name */
    @Test
    void test13(){

    1. List<Person> personList = Arrays.asList(
    2. new Person("Java旅途",18),
    3. new Person("Java旅途",20),
    4. new Person("Java旅途",20)
    5. );
    6. personList.stream()
    7. .map(Person::getName)
    8. .forEach(System.out::println);

    }

  • flatMap——接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流生成一个流。

    // 将字符串转换为字符,并将字符放进list返回
    static Stream filterCharcter(String string){

    1. List<Character> list = new ArrayList<>();
    2. for (Character ch : string.toCharArray()){
    3. list.add(ch);
    4. }
    5. return list.stream();

    }

    @Test
    void test13(){

    1. List<String> list = Arrays.asList("aaa","bbb","ccc");
    2. list.stream()
    3. .flatMap(LamdbaApplicationTests::filterCharcter)
    4. .forEach(System.out::println);

    }

2.3 排序

  • sorted()——自然排序(comparable)
  • sorted(comparator com)——定制排序(comparator )

    /* 定制排序,e1和e2按age排序,age一样按name排 */
    @Test
    void test14(){

    1. List<Person> personList = Arrays.asList(
    2. new Person("Java旅途",18),
    3. new Person("Java旅途",20)
    4. );
    5. personList.stream()
    6. .sorted((e1,e2) -> {
    7. if(e1.getAge() == e2.getAge()){
    8. return e1.getName().compareTo(e2.getName());
    9. }else{
    10. return e1.getAge()+"".compareTo(e2.getAge()+"");
    11. }
    12. }).forEach(System.out::println);

    }

三、终止操作

3.1 查找与匹配

完善一下Person

  1. @Data
  2. public class Person implements Serializable {
  3. private static final long serialVersionUID = -7008474395345458049L;
  4. private String name;
  5. private int age;
  6. private Status status;
  7. public Person() {
  8. }
  9. public Person(String name, int age) {
  10. this.name = name;
  11. this.age = age;
  12. }
  13. public Person(String name, int age, Status status) {
  14. this.name = name;
  15. this.age = age;
  16. this.status = status;
  17. }
  18. public enum Status {
  19. FRER,
  20. BUSY;
  21. }
  22. }
  • allMatch——检查是否匹配所有元素

    /* 是否所有元素都是Fire状态,是返回true */
    @Test
    void test15(){

    1. List<Person> personList1 = Arrays.asList(
    2. new Person("Java旅途",18, Person.Status.FRER),
    3. new Person("Java旅途",20, Person.Status.BUSY)
    4. );
    5. boolean b = personList1.stream()
    6. .allMatch(e -> e.getStatus().equals(Person.Status.FRER));
    7. System.out.println(b);

    }

  • anyMatch——检查是否至少匹配一个元素

    @Test
    void test15(){

    1. List<Person> personList1 = Arrays.asList(
    2. new Person("Java旅途",18, Person.Status.FRER),
    3. new Person("Java旅途",20, Person.Status.BUSY)
    4. );
    5. boolean b = personList1.stream()
    6. .anyMatch(e -> e.getStatus().equals(Person.Status.FRER));
    7. System.out.println(b);

    }

  • noneMatch——检查是否所有元素都不匹配

    @Test
    void test15(){

    1. List<Person> personList1 = Arrays.asList(
    2. new Person("Java旅途",18, Person.Status.FRER),
    3. new Person("Java旅途",20, Person.Status.BUSY)
    4. );
    5. boolean b = personList1.stream()
    6. .noneMatch(e -> e.getStatus().equals(Person.Status.FRER));
    7. System.out.println(b);

    }

  • findFirst——返回第一个元素

    @Test
    void test15(){

    1. List<Person> personList1 = Arrays.asList(
    2. new Person("Java旅途",18, Person.Status.FRER),
    3. new Person("Java旅途",20, Person.Status.BUSY)
    4. );
    5. Optional b = personList1.stream()
    6. .findFirst();
    7. System.out.println(b.get());

    }

  • findAny——返回当前流中的任意元素

    @Test
    void test15(){

    1. List<Person> personList1 = Arrays.asList(
    2. new Person("Java旅途",18, Person.Status.FRER),
    3. new Person("Java旅途",20, Person.Status.BUSY)
    4. );
    5. Optional b = personList1.stream()
    6. .findAny();
    7. System.out.println(b.get());

    }

  • count——返回流中元素的总数

  • max——返回流中最大值
  • min——返回流中最小值

3.2 规约

  • reduce(T identity, BinaryOperator)/reduce(BinaryOperator)——可以将流中元素反复结合起来,得到一个值。

    /* reduce 第一个参数是起始值 */
    @Test
    void test16(){

    1. List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
    2. Integer sum = list.stream()
    3. .reduce(0,(x,y) -> x+y);
    4. System.out.println(sum);
    5. Optional<Integer> reduce = list.stream()
    6. .reduce((x, y) -> x + y);
    7. System.out.println(reduce.get());

    }

3.3 收集

  • collect——将流转化为其他形式。接收一个Collector接口的实现。用于给Stream中元素做汇总的方法。

    /* 取出名字放在一个list中 */
    @Test
    void test16(){

    1. List<Person> personList1 = Arrays.asList(
    2. new Person("Java旅途",18, Person.Status.FRER),
    3. new Person("Java旅途",20, Person.Status.BUSY)
    4. );
    5. List<String> collect = personList1.stream()
    6. .map(Person::getName)
    7. .collect(Collectors.toList());
    8. collect.forEach(System.out::println);

    }

Optional常用方法

Optional类是一个容器类,代表一个值存在或不存在,原来用null表示一个值不存在,现在Optional可以更好的表达这个概念。并且可以避免空指针异常。

  1. Optional.of(T t) ——创建一个Optional实例
  2. Optional.empty()——创建一个空的optional实例
  3. Optional.ofNullable(T t)——若t不为null,创建optional实例,否则创建空实例
  4. isPresent()——判断是否包含值
  5. orElse(T t)——如果调用对象包含值,返回该值,否则返回 t
  6. orElseGet(Supplier s)——如果调用对象包含值,返回该值,否则返回 s 获取的值
  7. map(Function f)——如果有值对其处理,并返回处理后的Optional,否则返回Optional.empty()
  8. flatMap(Function mapper)——与map类似,要求返回值必须是Optional

发表评论

表情:
评论列表 (有 0 条评论,538人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Java8——Stream

    `Stream`是数据渠道,用于操作集合、数组等生成的元素序列。 `Stream`操作的三个步骤: 创建Stream 中间操作 终止操作 一、获取st

    相关 Java8 Stream操作

    java8中的流式操作是一个很重要的内容 ![stream主要流操作][stream] 上图列出了stream主要流操作,我们可以看到,其实流操作可以类比我们的sql