Java-1207

Stream API

  1. 流的概念:

    1. 是数据渠道,用于操作数据源所生成的元素序列。集合讲的是数据,流讲的是计算
    2. 注意
      1. Stream自己不会存储元素
      2. Stream不会改变源对象。相反,他们会返回一个持有结果的新的Stream
      3. Stream操作是延迟执行的。意味着他们会等到需要结果的时候才会执行。
  2. 步骤

    1. 创建Stream
    2. 中间操作
    3. 终止操作
  3. 创建stream

    1. 可以通过collection系列集合提供的stream()或parallelStream()方法获取,第一个是串行流,第二个是并行流。

      List<String>list = new ArrayList<>();
      Stream<String> stream = list.stream();
      
    2. 通过Arrays中的静态方法stream()获取数组流

      List<String>list = new ArrayList<>();
      Stream<String> stream = list.stream();
      
    3. 通过Stream类中的静态方法of()

      Stream<String> stringStream = Stream.of("aa", "bb", "cc");
      
    4. 创建无限流

      //  迭代
      Stream<Integer> integerStream = Stream.iterate(0, (x) -> x + 2);
      
      //  生成
      Stream<Double> doubleStream = Stream.generate(Math::random);
      
  4. 中间操作:

    1. 惰性求值:多个中间操作连接成一个流水线,除非流水线触发终止操作,否则中间操作不会执行任何处理。在终止操作时一次性全部处理。

    2. 筛选与切片操作

      1. Filter:接收lambda,从流中排除某些元素

        1. 内部迭代:

        2. 惰性求值:

        3. filter(x -> x.getAge() > 10)
          
      2. limit:截断流,使其元素不超过给定数量

        1. 内部会先找到满足条件的前n个值,内部迭代操作也仅仅在这几个值进行,我们称之为短路

          employees.stream().filter(e->{
                      System.out.println("limit");
                         return  e.getSalary() > 5000;
                  }).limit(5).forEach(System.out::println);
          
      3. skip:跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回一个空流。与limit互补

      4. distinct:筛选,通过流所生成元素的hashcode( )和equals()去除重复元素

        1. 如果需要对Object进行去重,需要重写hashCode和equals方法
    3. 映射

      1. map(Function f):

        1. 接收Lambda,将元素转化为其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每一个元素上,并将其映射成一个新的元素。
        2. map操作返回的依然是流
        3. 经过map操作后的流的元素会变,根据map中Lambda的返回值变化。
      2. mapToDouble(ToDoubleFunction f)

      3. mapToInt(ToIntFunction f)

      4. mapToLong(ToLongFunction f)

      5. flatMap(Function f):接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。

      6. flatMap和Map的区别

        1. 二者的区别类似于add和addAll的区别,前者如果使用list2.add(list),结果会是将整个list作为一个元素放进list2,而list2.addAll(list),是将list里面的每个元素拆分开,以元素的方式存进去。
        public static Stream<Character> filterCharacter(String str){
                List<Character>list = new ArrayList<>();
                for(Character ch:str.toCharArray()){
                    list.add(ch);
                }
                return list.stream();
            }
        
            @Test
            public void test6(){
                List<String> list = Arrays.asList("aaa","bbb","ccc","ddd","eee");
        
                //  用map,返回Stream<Stream<Character>>
                Stream<Stream<Character>> streamStream = list.stream()
                        .map(TestStreamAPI2::filterCharacter);
                //  用flatMap,返回Stream<Character>
                Stream<Character> characterStream = list.stream()
                        .flatMap(TestStreamAPI2::filterCharacter);
            }
        
    4. 排序

      1. sorted():自然排序,按照对象指定的Comparable排序

      2. sorted(Comparator comp):定制排序Comparator

        employees.stream()
                        .sorted((e1,e2)->{
                            if(e1.getAge()!=e2.getAge()){
                                return -e1.getAge()+e2.getAge();
                            }else return e1.getName().compareTo(e2.getName());
                        }).forEach(System.out::println);
        
  5. 终止操作

    1. 查找与匹配

      1. allMatch():检查是否匹配所有元素,相当于全称量词

        boolean b = employees.stream()
                        .allMatch(e -> e.getStatus().equals(Status.BUSY));
        
      2. anyMatch():是否存在一个匹配值,相当于存在量词

      3. noneMatch():检查是否没有匹配的元素,相当于存在量词的非

      4. findFirst():找到第一个元素,返回optional对象

        1. Optional对象:一个容器类,为了避免空指针异常,当返回的值有可能为空时,就会封装进optional

        2. orElse方法:如果当前容器封装的对象指针为空,可以搞一个替代的对象

          Optional<Employee> first = employees.stream()
                          .sorted(Comparator.comparingDouble(Employee::getSalary))
                          .findFirst();
          
                  first.orElse(new Employee());
          
      5. findAny():找到任意一个元素

      6. count:返回流中元素总数

        long count = employees.stream().count();
        
      7. min:返回流中最小值

        Optional<Double> min = employees.stream().map(Employee::getSalary).min(Double::compare);
                System.out.println(min.get());
        
      8. max:返回流中的最大值

    2. 归约 reduce(T identity, Binaryoperator) / reduce(BinaryOperator) 可以将流中元素反复结合起来,得到一个值。

      1. reduce(T identity, Binaryoperator) : 第一个参数为启始值,第二个参数为运算式

      2. map-reduce 连用成为map-reduce模式:

        Optional<Double> map-reduce = employees.stream()
                        .map(Employee::getSalary)
                        .reduce(Double::sum);
                System.out.println();
        
    3. 收集 collect-将流转换为其他形式。接收一个collector接口的实现,用于Stream中元素汇总方法

      1. collect(Collector c )

        //  使用list
                List<String> collect = employees.stream()
                        .map(Employee::getName)
                        .collect(Collectors.toList());
                collect.forEach(System.out::println);
        
                //  使用set
                Set<String> set = employees.stream()
                        .map(Employee::getName)
                        .collect(Collectors.toSet());
                set.forEach(System.out::println);
        
                //  使用构造
                HashSet<String> stringHashSet = employees.stream()
                        .map(Employee::getName)
                        .collect(Collectors.toCollection(HashSet::new));
        
      2. Collector.counting:收集总数

        Long aLong = employees.stream().collect(Collectors.counting());
        
      3. Collector.avg : 平均值

        Double avg = employees.stream().collect(Collectors.averagingDouble(Employee::getSalary));
        
      4. Collector.summing :总和

        Double sum = employees.stream().collect(Collectors.summingDouble(Employee::getSalary));
        
      5. 最大值:

        Optional<Employee> max = employees.stream()
                      .collect(Collectors.maxBy(Comparator.comparingDouble(Employee::getSalary)));
        
      6. 最小值

         Optional<Double> min = employees.stream().map(e -> e.getSalary())
                        .collect(Collectors.minBy(Double::compareTo));
        
        //	或者
        Optional<Double> min = employees.stream().map(Employee::getSalary).min(Double::compareTo);
        
      7. 分组:

        Map<Status, List<Employee>> statusListMap = 
                        employees.stream().collect(Collectors.groupingBy(Employee::getStatus));
        
      8. 多级分组

        Map<Status, Map<String, List<Employee>>> statusMapMap = employees.stream()
                        .collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy(e -> {
                    if (e.getAge() > 50) return "老年";
                    else if (e.getAge() <= 50 && e.getAge() > 30) return "中年";
                    else return "青年";
                })));
        
      9. 分区

        Map<Boolean, List<Employee>> listMap = employees.stream()
                        .collect(Collectors.partitioningBy(e -> e.getSalary() > 8000));
        
      10. 统计

        DoubleSummaryStatistics collect = employees.stream()
                        .collect(Collectors.summarizingDouble(Employee::getSalary));
                System.out.println(collect.getAverage());
                System.out.println(collect.getMax());
                System.out.println(collect.getSum());
        
      11. 字符串连接

        String collectStr = employees.stream().map(Employee::getName).collect(Collectors.joining(","));
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值