/*
 * Stream的三个操作步骤
 *
 * 1、创建Stream
 *
 * 2、中间操作
 *
 * 3、终止操作(终端操作)
 */


 //创建Stream
   应用idea时 比如:是数组转换为stream流
          Integer[] nums=new Integer[]{1,2,3,4,5,6};
          nums.stream  会自动转换为  Arrays.stream(nums)


//中间操作
  
    筛选与切片
    filter--接收Lambda,从流中排除某些元素。
    limit--截断流,使其元素不超过给定数量
    skip(n)--跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回一个空流。与limit(n)互补
    (跳过N个,从N+1个开始取)
    distinct--筛选,通过流所生成元素的hashcode和equals去除重复元素
 
    排序
    sorted()--自然排序                                                  
    sorted(comparator com)--定制排序(x,y)->sorted(Comparator.comparing(Transaction::getValue))
 
     映射
     Map --接受lambda,将元素转换成其他形式或提取信息。接受一个函数作为参数,该函数会被应用到每个元素上,应将其映射成一个新的元素
     例子:将元素替换成其他元素
      List<Student> students = Arrays.asList(
            new Student("张三", "男", 11),
            new Student("李四", "女", 11),
            new Student("王五", "男", 22),
            new Student("赵六", "女", 21),
            new Student("赵六", "女", 21),
            new Student("赵六", "女", 21));
    List<Integer> collect = students.stream()
                 .map(x -> 1)
                .collect(Collectors.toList());
    输出结果为:[1, 1, 1, 1, 1, 1]
   
  //终止操作(终端操作)
    * 查找与匹配
     * allMatch -- 检查是否匹配所有元素
     * anyMatch -- 检查是否至少匹配一个元素
     * noneMatch --检查是否没有匹配所有元素
     * findFirst --返回第一个元素
     * findAny --- 返回当前流中的任意元素
     * count ----- 返回流中元素的总个数
     * max -----   返回流中最大值
     * min -----   返回流中最小值

     例子:
       @Test
    public void test1() {
        boolean b = stus.stream().allMatch(x -> x.getAge() > 10);
        System.out.println(b);
        boolean b1 = stus.stream().anyMatch(x -> x.getAge() < 20);
        System.out.println(b1);
        boolean aaa = stus.stream().noneMatch(x -> x.getStatus().equals("BUSY"));
        System.out.println(aaa);
        Optional<Student> first = stus.stream().findFirst();
        System.out.println(first);
        Optional<Student> any = stus.stream().findAny();
        System.out.println(any);
        long count = stus.stream().count();
        System.out.println(count);
        Optional<Student> min = stus.stream().min((x, y) -> Integer.compare(x.getAge(), y.getAge()));
        System.out.println(min);
        Optional<Student> max = stus.stream().max((x, y) -> Integer.compare(x.getAge(), y.getAge()));
        System.out.println(max);
    }
    
      归约
    reduce(T identity,BinaryOperator)/reduce(BinaryOperator)--可以将流中元素反复结合起来,得到一个值

      收集
    collect --将流转换为替他形式。接收一个Collector接口的实现,用于给Stream中元素做汇总的方法
    Collector接口中方法的实现决定了如何对流执行收集操作(如收集到List、Set、Map)
    但是Collectors实用类提供了很多静态方法,可以方便地创建常用收集器实例。
    1、分区partitioningBy (分为true和false)
      stus.stream().collect(Collectors.partitioningBy((x) -> x.getAge() > 20));
    2、分组 (按照状态分组)groupingBy
      stus.stream().collect(Collectors.groupingBy(Student::getStatus));
    3、最小值
      stus.stream().collect(Collectors.minBy((x, y) -> Integer.compare(x.getAge(), y.getAge())));
    4、最大值
      stus.stream().collect(Collectors.maxBy((x, y) -> Integer.compare(x.getAge(), y.getAge())));
    5、总和
      stus.stream().collect(Collectors.summingDouble(Student::getAge));
      //stus.stream().map(Student::getAge).reduce(Integer::sum);
    6、平均值
       stus.stream().collect(Collectors.counting());
        
    7、总数
       stus.stream().collect(Collectors.averagingDouble(Student::getAge));
       long count = stus.stream().count();