1、什么是函数式编程
1)函数式编程指的是一种编程范式,它将计算描述为一种表达式求值,函数式编程关心的是数据(代数结构的映射关系)。
2)函数式编程中的函数不是指命令式编程中的函数,而是指数学中的函数,即自变量的映射(一种东西和另一种东西之间的对应关系)。也就是说,一个函数的值仅决定于函数参数的值,不依赖于其他状态。
3)函数式编程是java8的一大特色,也就是将函数作为一个参数传递给指定方法。别人传的要么是基本数据类型,要么就是地址引用 ,我们要传一个“动作”。
2、java中的函数式编程
1) Lambda表达式:JAVA8为支持函数式编程引入的新语法,而为了支持lambda表达式,才有了函数式接口。
2)函数式接口:指的是有且只有一个未实现方法的接口,一般通过FunctionalInterface这个注解来表明某个接口是一个函数式接口。函数式接口是Java支持函数式编程的基础。
3、JAVA提供常见的几种函数式编程的接口
1)Supplier: 数据提供器,可以提供 T 类型对象;无参的构造器,提供了 get 方法;
//创建supplier 申明类型为String (特别注意:此时并不会调用对象的构造方法,即不会创建对象)
Supplier<String> supplier = String::new;
//有参函数式写法
Supplier<String> supplier1 = () -> new String("这是一个字符串");
System.out.println(supplier1.get()); //这是一个字符串
//调用get()方法,此时会调用对象的构造方法,即获得到真正对象
String s1 = supplier.get();
每次get都会调用构造方法,即获取的对象不同
String s2 = supplier.get();
//我们可以用‘==’比对一下引用,发现是fasle,即两个对象不同
System.out.println(s1 == s2); //false
2)Consumer: 数据消费器, 接收一个 T类型的对象,无返回值,通常用于设置T对象的值; 单参数无返回值的行为接口;提供了 accept, andThen 方法;
StringBuilder sb = new StringBuilder("Hello ");
//定义一个 consumer 进行字符串追加
Consumer<StringBuilder> consumer = (str) -> str.append("Jack!");
//accept 我理解为调用该函数
//consumer.accept(sb);
System.out.println(sb.toString()); // Hello Jack!
//定义另一个 consumer 进行字符串追加
Consumer<StringBuilder> consumer1 = (str) -> str.append(" Bob!");
//andThen 执行后返回组合的consumer 当执行accept时,会按照consumer、consumer1的顺序进行
consumer.andThen(consumer1).accept(sb);
System.out.println(sb.toString()); // Hello Jack! Bob!
3)Predicate: 条件测试器,接收一个 T 类型的对象,返回布尔值,通常用于传递条件函数; 单参数布尔值的条件性接口。提供了 test (条件测试) , and-or- negate(与或非) 方法。
//定义一个predicate 比较字符串的长度是否大于4
Predicate<String> predicate = s -> s.length()>4;
//定义一个predicate 比较字符串的长度是否小于2
Predicate<String> predicate1 = s -> s.length()<2;
//按照函数表达式比对
System.out.println(predicate.test("123")); //false
System.out.println(predicate.test("12345")); //true
//按照函数表达式比对 结果取反
System.out.println(predicate.negate().test("123")); //true
System.out.println(predicate.negate().test("12345")); //fasle
//组合条件,满足predicate 或 predicate1的条件才成立
System.out.println(predicate.or(predicate1).test("1")); //true
System.out.println(predicate.or(predicate1).test("123")); //fasle
4)Function<T,R>: 数据转换器,接收一个 T 类型的对象,返回一个 R类型的对象; 单参数单返回值的行为接口;提供了 apply, compose, andThen, identity 方法;
//定义一个Functon <入参类型,出参类型> 对入参数进行乘100操作
Function<Integer, Integer> function = (a) -> a * 100;
//定义一个Functon <入参类型,出参类型> 对入参数进行加1操作
Function<Integer, Integer> function1 = (a) -> a + 1;
System.out.println(function.apply(5)); //5 * 100 = 500
//先执行参数(即也是一个Function)的,再执行调用者(同样是一个Function)
System.out.println(function1.compose(function).apply(5)); //(5 * 100) + 1 = 501
//先执行调用者,再执行参数,和compose相反
System.out.println(function1.andThen(function).apply(5)); //(5 + 1) * 100 = 600
//返回当前正在执行的方法
Function.identity()