函数式编程、函数式接口、兰姆达表达式、方法引用、stream

耗尽温柔 提交于 2019-11-27 03:40:01
package com.example.demo;

import org.assertj.core.util.Lists;

import javax.sound.midi.SysexMessage;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 参考:https://blog.csdn.net/EQuaker/article/details/86561781
 *       https://www.cnblogs.com/yunqing/p/9221117.html
 * 1. 函数式编程:(两个特点)
 *      可以把函数作为参数传递给另一个函数,也就是所谓的高阶函数
 *      可以返回一个函数,这样就可以实现闭包或者惰性计算(闭包:A函数返回B函数,B函数使用了A中的变量,则相当于扩大了A中变量的作用范围;放回方法,可以延迟执行)
 * 2. 函数式接口(只有一个抽象方法,可以有多个默认实现方法或静态方法)
 *      Consumer<T>:消费性接口
 *      Supplier<T> 供给型接口
 *      Function<T,R> 函数型接口
 *      Predicate<T> 断言型接口
 * 3. 兰姆达表达式(函数式接口的实现)
 *      (参数,一个时可省略括号) -> {函数实现,一条语句可以不用括号及返回return}
 * 4. 方法引用(进一步简化lambda表达式的声明)
 *      objectName::instanceMethod
 *      ClassName::staticMethod
 *      ClassName::instanceMethod   (把lambda表达式的第一个参数当成instanceMethod的目标对象,其他剩余参数当成该方法的参数。)
 * 5. 流stream
 *          1).Stream是元素的集合,这点让Stream看起来用些类似Iterator;
 *          2).可以支持顺序和并行的对原Stream进行汇聚的操作;(直接告诉程序要做什么,如转换成大写,怎么做(如并行还是串行等)让计算机自己决定)
 *    使用步骤:stream创建、转换、聚合(Reduce)
 *    (转换操作都是lazy的,多个转换操作只会在汇聚操作(见下节)的时候融合起来,一次循环完成。
 *    我们可以这样简单的理解,Stream里有个操作函数的集合,每次转换操作就是把转换函数放入这个集合中,
 *    在汇聚操作的时候循环Stream对应的集合,然后对每个元素执行所有的函数。)
 *    (汇聚操作(也称为折叠)接受一个元素序列为输入,反复使用某个合并操作,把序列中的元素合并成一个汇总的结果。
 *    比如查找一个数字列表的总和或者最大值,或者把这些数字累积成一个List对象。Stream接口有一些通用的汇聚操作,
 *    比如reduce()和collect();也有一些特定用途的汇聚操作,比如sum(),max()和count()。)
 *
 */
public class TestLamda {

    public static void main(String[] args){
//        testStream();
        testConsumer(10,(i) -> System.out.println(i*10));
    }

    static void testConsumer(int i,Consumer<Integer> consumer){
        consumer.accept(i);
    }

    public static void testStream(){
        //1. 创建:Collection(集合子类).stream();Stream.of;generate;iterate
        //2. 转换:distinct;filter;map;flatMap;peek;limit;skip;
        //3. 汇聚:
        //          1)可变汇聚:collect      2)其他汇聚:reduce;count;allMatch;anyMatch;findFirst;noneMatch;max;min
        List<Integer> nums = Lists.newArrayList(1,null,3,4,null,6);
        Stream<Integer> integerStream = Stream.of(1, 2, 3, 5);
        Stream.generate(() -> Math.random());
        Stream.generate(Math::random);
        Stream.iterate(1, item -> item + 1).limit(10).forEach(System.out::println);
        System.out.println("result:  "+nums.stream().filter(s -> s == null).count());
        System.out.println("sum is:"+nums.stream().filter(num -> num != null).distinct().mapToInt(num -> num * 2)
                .peek(System.out::println).skip(2).limit(4).sum());
        //汇聚
        List<Integer> nums2 = Lists.newArrayList(1,1,null,2,3,4,null,5,6,7,8,9,10);
        List<Integer> numsWithoutNull = nums2.stream().filter(num -> num != null).
                collect(() -> new ArrayList<Integer>(),//生成容器
                        (list, item) -> list.add(item),//元素添加到容器
                        (list1, list2) -> list1.addAll(list2));//多个结果容器合并操作
        List<Integer> numsWithoutNull2 = nums2.stream().filter(num -> num != null).
                collect(Collectors.toList());
        List<Integer> ints = Lists.newArrayList(1,2,3,4,5,6,7,8,9,10);
        System.out.println("ints sum is:" + ints.stream().reduce((sum, item) -> sum + item).get());

    }


}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!