欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

lambda表达式实例(续)

程序员文章站 2022-04-07 18:03:45
lambda表达式实例(续)及其说明public static void main(String[] args) { /** * 3.流的终止操作 * 3.1 匹配和聚合操作 * allMatch:接收一个 Predicate 函数,当流中每个元素都符合该断言时才返回true,否则返回false * noneMatch:接收一个 Predicate 函数,当流中每个元素都不符合该断言时才返回tr...

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);
    });
}

本文地址:https://blog.csdn.net/weixin_53111201/article/details/112055893