lambda表达式实例(续)

lambda表达式实例(续)及其说明

public static void main(String[] args) {

    /**
     * 3.流的终止操作
     *      3.1 匹配和聚合操作
     *              allMatch:接收一个 Predicate 函数,当流中每个元素都符合该断言时才返回true,否则返回false
     *              noneMatch:接收一个 Predicate 函数,当流中每个元素都不符合该断言时才返回true,否则返回false
     *              anyMatch:接收一个 Predicate 函数,只要流中有一个元素满足该断言则返回true,否则返回false
     *              findFirst:返回流中第一个元素
     *              findAny:返回流中的任意元素
     *              count:返回流中元素的总个数
     *              max:返回流中元素最大值
     *              min:返回流中元素最小值
     *      3.2 归约操作
     *              Optional<T> reduce(BinaryOperator<T> accumulator):
     *                  第一次执行时,accumulator函数的第一个参数为流中的第一个元素,第二个参数为流中元素的第二个元素;
     *                  第二次执行时,第一个参数为第一次函数执行的结果,第二个参数为流中的第三个元素;依次类推。
     *              T reduce(T identity, BinaryOperator<T> accumulator):
     *                  流程跟上面一样,只是第一次执行时,accumulator函数的第一个参数为identity,而第二个参数为流中的第一个元素。
     *              <U> U reduce(U identity,BiFunction<U, ? super T, U> accumulator,BinaryOperator<U> combiner):
     *                  在串行流(stream)中,该方法跟第二个方法一样,即第三个参数combiner不会起作用。在并行流(parallelStream)中,我们知道流被fork

join出多个线程进行执行,此时每个线程的执行流程就跟第二个方法reduce(identity,accumulator)一样,而第三个参数combiner函数,则是将每个线程的执行结果当成一个新的流,然后使用第一个方法reduce(accumulator)流程进行规约。
* 3.3 收集操作
* collect:接收一个Collector实例,将流中元素收集成另外一个数据结构。
* Collector<T, A, R> 是一个接口,有以下5个抽象方法:
* Supplier supplier():创建一个结果容器A
* BiConsumer<A, T> accumulator():消费型接口,第一个参数为容器A,第二个参数为流中元素T。
* BinaryOperator combiner():函数接口,该参数的作用跟上一个方法(reduce)中的combiner参数一样,将并行流中各
个子进程的运行结果(accumulator函数操作后的容器A)进行合并。
* Function<A, R> finisher():函数式接口,参数为:容器A,返回类型为:collect方法最终想要的结果R。
* Set characteristics():返回一个不可变的Set集合,用来表明该Collector的特征。有以下三个特征:
*
* CONCURRENT:表示此收集器支持并发。(官方文档还有其他描述,暂时没去探索,故不作过多翻译)
* UNORDERED:表示该收集操作不会保留流中元素原有的顺序。
* IDENTITY_FINISH:表示finisher参数只是标识而已,可忽略。
*/

    List<Integer> integers = Arrays.asList(1, 2, 6, 7, 9);
    //必须每一个元素都符合该断言  断言是(c>10 就是断言 1=1 也叫断言 )
    //false
    System.out.println(integers.stream().allMatch(c -> c > 10));
    //true
    System.out.println(integers.stream().noneMatch(c -> c > 10));
    //true
    System.out.println(integers.stream().anyMatch(c -> c > 4));
    //返回流中第一个元素
    System.out.println(integers.stream().findFirst().get());
    //返回流中的随机一个元素
    System.out.println(integers.stream().findAny().get());
    //获取流中的记录条数
    System.out.println(integers.stream().count());
    //最大值
    System.out.println(integers.stream().max(Integer::compareTo).get());
    //最小值 Integer::compareTo Integer compareTo 比较 等同下边这种写法

    System.out.println(integers.stream().min(Integer::compareTo).get());
    /**
     * Integer::compareTo
     * 等同于
     * Integer s=1;
     * s.compareTo(1);
     * s.compareTo(1) 用于字符串和对象比较 或者两个值的比较
     * return: 0 参数字符串等于当前参数字符串 返回值0
     * return: -1  参数字符串小于当前参数字符串 返回值小于0的值
     * return:  1 参数字符串大于当前参数字符串 返回值大于0的值
     *
     */
    List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

    /**
     *  Optional<T> reduce(BinaryOperator<T> accumulator):
     *                                   x1                              y1
     *      第一次执行时,accumulator函数的第一个参数为流中的第一个元素,第二个参数为流中元素的第二个元素;
     *      看上边这句话 看完了
     *      第二次执行时,第一个参数为第一次函数执行的结果,第二个参数为流中的第三个元素;依次类推。
     *  T reduce(T identity, BinaryOperator<T> accumulator):
     *
     *      流程跟上面一样,只是第一次执行时,accumulator函数的第一个参数为identity,而第二个参数为流中的第一个元素。
     *
     * <U> U reduce(U identity,BiFunction<U, ? super T, U> accumulator,BinaryOperator<U> combiner):
     *       在串行流(stream)中,该方法跟第二个方法一样,即第三个参数combiner不会起作用。在并行流(parallelStream)中,
     *       我们知道流被fork join出多个线程进行执行,此时每个线程的执行流程就跟第二个方法reduce(identity,accumulator)一样,
     *       而第三个参数combiner函数,则是将每个线程的执行结果当成一个新的流,然后使用第一个方法reduce(accumulator)流程进行规约。
     *
     */

    List<Integer> bxStream = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
    //这个要知道是啥 这是并行流内置forkjoin线程池 所以称为并行流 其效率是stream的数倍
   bxStream.parallelStream();

    //这一行说的是 这个集合整个结果相加 BinaryOperator(这个也是一个lambda表达式

    //(a,b)->a+b  x1代表当前第一个元素  x2代表第二个元素  x1, y1就代表这 整个stream流中的所有元素 x1+y1是对所有元素都执行这个操作
    //此操作被称为归约 (可理解为归类约定)
    //(x1, y1) -> x1 + y1 --------------------> 1+2+3+4+5+6+7+8+9+10
    System.out.println("归约result:" + list.stream().reduce((x1, y1) -> x1 + y1).get());
    //T identity 这个就是把 identity 当前元素为x1 其实集合的数据 应该是 10,1, 2, 3, 4, 5, 6, 7, 8, 9, 10
    System.out.println(list.stream().reduce(10, (x1, y1) -> x1 + y1));
  //  List<Integer> bxStream = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); 执行流程就是 0-1, 2, 3, 4, 5, 6, 7, 8, 9, 10
    /**
     * 定义是
     * 在串行流(stream)中,该方法跟第二个方法一样,即第三个参数combiner不会起作用。
     *
     * 在并行流(parallelStream)中,
     *  我们知道流被fork join出多个线程进行执行,此时每个线程的执行流程就跟第二个方法reduce(identity,accumulator)一样,
     *  而第三个参数combiner函数,则是将每个线程的执行结果当成一个新的流,然后使用第一个方法reduce(accumulator)流程进行规约
     *  0, (x1, x2) -> x1 * x2  ======================>这个最终结果执行为0 0乘以多少都是0呗 很简单
     *  则是将每个线程的执行结果当成一个新的流 (重点就是这句话 它会把 [0, (x1, x2) -> x1 * x2 ] 这个的执行结果当成一个新的流去执行第三个)
     *  新的流很明显只有一个数据就是0 0+0-0 都是0
     *
     *  总结:
     *      串行流(Stream)
     *      reduce(T,accumulator,accumulator) 第三个函数式是不起作用的
     *      并行流(parallelStream)
     *      reduce(T,accumulator,accumulator) 会先执行第二个函数式,然后把第二个函数试执行的结果当做一个新的流 去执行第三个函数式
     */
    System.out.println("假设1:" + list.stream().reduce(0, (x1, x2) -> x1 - x2, (x1, x2) -> x1 * x2));
        System.out.println("假设2:" + list.stream().reduce(0, (x1, x2) -> x1 * x2, (x1, x2) -> x1 - x2));
        System.out.println("并行假设1:" + list.parallelStream().reduce(0, (x1, x2) -> x1 * x2, (x1, x2) -> x1 - x2));
        System.out.println("规约结果集" + reduce);

    //Collectors工具库
    List<Student> students = new ArrayList();
    students.add(new Student("aa", 10));
    students.add(new Student("bb", 20));
    students.add(new Student("cc", 30));
    //获取年龄属性并转成List
    /**
     * public static <T>
     *     Collector<T, ?, List<T>> toList() {
     *         return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
     *                                    (left, right) -> { left.addAll(right); return left; },
     *                                    CH_ID);
     *     }
     *      CH_ID:此处没啥用
     *     创建一个新的arrayList 并add left,right 将当前的数据addAll 到一个新的list 并return
     *
     *     static final Set<Collector.Characteristics> CH_ID
     *             = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH));
     *
     *             枚举类 了解就行
     *             CONCURRENT:表示此收集器支持并发。(官方文档还有其他描述,暂时没去探索,故不作过多翻译)
     *             UNORDERED:表示该收集操作不会保留流中元素原有的顺序。
     *             IDENTITY_FINISH:表示finisher参数只是标识而已,可忽略。
     *     */
       students.stream().map(Student::getAge).collect(Collectors.toList()).forEach(System.out::println);
        //获取年龄属性并转成Set
        students.stream().map(Student::getAge).collect(Collectors.toSet()).forEach(System.out::println);
        //获取当前学生并转成map 我想起来了Student::getName, Student::getAge)
         Map<String, Integer> collect = students.stream().collect(HashMap::new, (m, v) -> m.put(v.getName(), v.getAge()), HashMap::putAll);
         map遍历方式
         collect.forEach((k, v) -> {
           System.out.println("键" + k + "," + "值" + v);
         });

    //学生姓名分隔连接 都采用Collectors工具类  joining 分隔 Collectors.joining(",")
    System.out.println(students.stream().map(Student::getName).collect(Collectors.joining(",")));
    //计算学生年龄总和 这是一种 用Collectors工具类 Collectors.summingInt(Student::getAge))
    //mapToInt这个啥意思 获取当前对象中的Int类型 最终返回一个Int流
    //maptoint是intStream这个 intStream获取当前对象中的Int类型 最终返回一个Int流
    //IntStream 其实是和 Stream类似的换个名字而已 单操作Integer类型 你发现其实方法都一样的 Int会有几个独有的方法相加等等
    //Stream是流
    IntStream intStream = students.stream().mapToInt(Student::getAge);
    System.out.println(students.stream().collect(Collectors.summingInt(Student::getAge)));
    //获取当前学生的最大年龄
    System.out.println(students.stream()
            .map(Student::getAge)
            .collect(Collectors.toList())
            .stream()
            .max(Integer::compareTo).get());
    //使用Collectors 工具类获取当前学生的最大年龄 Collectors.maxBy(Integer::compareTo)
    System.out.println(students.stream().map(Student::getAge).collect(Collectors.maxBy(Integer::compareTo)).get());
    //获取最小年龄 大的max小是min
    System.out.println(students.stream().map(Student::getAge).collect(Collectors.minBy(Integer::compareTo)).get());
    Integer integer = students.stream().map(Student::getAge).collect(Collectors.toList()).stream().min(Integer::compareTo).get();
    //toList 是一个新的对象 新的List可以有Stream
    //println 是 PrintStream类的非静态方法
    /**
     * System.out::println
     * PrintStream out = System.out;
     *         Consumer<String> fun2 = out::println;
     *         fun2.accept("hello");
     *         students.stream().forEach(System.out::println);
      *         (Student::getAge)          (s->s.getAge())  Predicate->条件筛选
     *         左边用于获取属性没办法去做.equals 等操作   适用于比较并可拼接(条件筛选 多用于过滤)
     *
     */
     //(Student::getAge)能实现的(s->s.getAge)它都能,但是(s->s.getAge)它能实现的(Student::getAge)他不能
     //平均年龄 最后两 Collectors.averagingInt() averaging  avg全称
    System.out.println(students.stream().collect(Collectors.averagingInt(Student::getAge)));
    //分组
    students.stream().collect(Collectors.groupingBy(Student::getAge)).forEach((k, v) -> {
        System.out.println("k" + k + "v" + v);
    });
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值