函数式编程
概述:
是相较于 命令式编程 的一种编程范式;
是一种如何 搭建应用程序 的方法论,不是一种具体的技术;
具体的,能够熟练应用Stream流相关的API ,lamdba 表达式 到工作中,就说明你会函数式编程
函数式编程:关注做什么,说白了,内置函数库已经将需要的功能实现好了,直接用
命令式编程:关注怎么做,具体实现细节需要我们自己代码编写
为什么要使用函数式编程:
使用 lambda 能够使得代码更加的简洁
Lambda 表达式:
其实也是一个匿名函数,它不去关心接口名,方法名,参数名,而是关心参数类型,参数个数,返回值信息
形式上: (i) -> i *2
即:参数列表 -> 函数体
本质:返回了一个 实现指定接口的对象实例
那么,是不是任意接口都是可以的呢?当然不是这样哈,这个接口必须是函数接口(java8新引入的接口特性)。
Jdk8 接口新特性:
1.函数接口:@FunctionalInterface ,这个接口有且仅有一个 要实现的非静态方法,函数接口包含了多个未实现的方法的话,就会报错。
现在回头想想:箭头左边是函数接口的参数 ,箭头右边是这个函数接口的具体实现
2. 默认实现的方法
需要注意,函数接口并不是只能有一个方法,可以是
多个默认实现了方法 + 1个未实现的非静态方法 的形式 ,如下:
@FunctionalInterface
interface Interface1{
// 1个未实现的非静态方法
int doubleNum(int i);
// 默认实现的方法
default int add(int x ,int y){
return x + y;
}
}
- 在 函数接口多重继承的时候,如果出现 同名的默认实现的方法,这个时候需要指定具体是哪个类的默认方法。
注意学习:接口的默认方法,如List
Java8 内置的函数接口:
- java已经帮我们定义好了一些常用的函数接口,就不用我们自己去定义了,我们仅关注自己的实现逻辑即可;
- 同时函数接口也支持链式编程
定义更少的接口,可以更加灵活的操作
那么常见内置的函数接口有哪些呢?
// 使用举例: 断言函数
// IntPredicate
Predicate<Integer> predicate = i -> i>0;
System.out.println(predicate.test(36));
// 使用举例:消费的接口使用
// IntConsumer
Consumer<String> consumer = s -> System.out.println(s);
consumer.accept("这里是消费的数据");
新的知识点 方法引用:
方法引用: 另外一种lambda的写法, 可以使得lambda 更加简洁;
当箭头右边函数的实现 恰好 可以通过调用一个其它类的方法来实现 ,我们就可以缩写标准lambda 表达式为 方法引用的方式,如下:
Consumer<String> consumer = s -> System.out.println(s);
// 等价 => 方法引用的方式
Consumer<String> consumer1 = System.out::println;
上面说到方法引用其实是lambda表达式的一种简化写法。所引用的方法其实是lambda表达式的方法体实现,语法也很简单,左边是容器(可以是类名,实例名),中间是"::",右边是相应的方法名。具体如下所示:
方法引用的3种形式:
1.静态方法 -> 类名::方法名
2.非静态方法,即成员方法
(ps:JDK编译器会自动会把当前实例 传入到每一个非静态方法里面,方法名为this,位置是第一个 )
第一种使用 实例::方法名
第二种使用 类名::方法名 这个时候的类名要多加一个参数,参考下图
3.构造函数的方法引用
主要分析输入参数个数
第一种无参数构造函数的方法引用: 类名::new ,提供者Supplier
第二种带参数构造函数的方法引用: 类名::new , 有参数Function
总之,找到函数的输入输出,就可以找到对应的内置的函数接口进行匹配
无参数的构造函数做方法引用:
带参数的构造函数做方法引用:
拓展一点点:
1.在Java里面是变量传递, 传递的不是 引用,是值 。引用置为null,而 值 还是存在的。
java只有值传递就完事了,基本类型传递值,引用类型 传递地址值,都属于值。执行下面案例就会明白
private static void test(List<String> list){
list = null;
}
public static void main(String[] args) {
List<String> list = new ArrayList<>();
// test(list); // []
// list = null; // null
System.out.println(list);
}
- Java中this关键字的由来
JDK编译器会自动会把当前实例 传入到每一个非静态方法里面,方法名为this,位置是第一个
参考:https://www.cnblogs.com/jianwei-dai/p/5819479.html