摘要:本人根据哔哩哔哩三更老师的教学视频而制作的笔记,感谢三更老师精彩的讲解!
目录
一、函数式编程的思想
1、思想:
面向对象的思想主要是关注对象能完成什么事情,而函数式编程思想就不再具体关注是哪个对象做什么事情了,函数式编程类似于数学中的函数,它更关注于数据以及对数据进行什么样的操作,其中,数据对应我们的参数列表,对数据进行的操作对应我们的方法体;
2、函数式编程的优点:
- 代码简洁明了、容易理解,避免了嵌套的for循环,省略掉的这些代码其实都是没有什么太大意义的一些格式化的代码 ;
- 方便于并发编程,不需要过分关注线程安全问题;
二、函数式接口
1、函数式接口:
函数式接口是指有且仅有一个抽象方法的接口,注意,指的是接口当中只有一个抽象方法,在jdk8当中, 除了有抽象方法之外,还可以有非抽象方法,但是我们只看抽象方法,如果你抽象方法只有一个,那就是函数式接口:
default:默认方法,有方法体
2、@FunctionalInterface注解:
函数式接口可以使用@FunctionalInterface注解标识,被该注解标注的接口具有多个非抽象方法时,则会编译报错,举例:
比如说我们这里定义一个接口,首先我加上一个注解@FunctionalInterface,这个时候它会报错,为什么呢? 因为你加上了它,说明你是想把它定义成函数式接口,但是现在里面一个抽象方法都没有:
那我如果定一个,你会发现是不是就不报错了:
那如果我定义两个呢,定义两个是不是也不符合函数式接口的要求啊,它这里会对它进行一个校验,不符合要求,它也会有一个对应的错误,给你提示:
三、Lambda表达式
lambda表达式是Java8的一个新特性,也是函数式编程的一个核心、基石,我们的Stream也是基于lambda表达式的基础上的
它主要优化的是某一些匿名内部类的写法,不是所有匿名内部类都可以使用Lambda表达式进行优化的---- 如果这个匿名内部类是一个函数式接口:接口当中只有一个抽象方法需要重写,那我们就可以用 lambda表达式对它进行一个简化。
1、lambda基本格式:
1.1 (参数列表) -> {方法体}
1.2 优化规则/省略规则:
参数的数据类型可以省略;
方法只有一个参数时小括号可以省略;
方法体只有一句代码时,大括号、return和唯一一句代码的分号可以省略
以上这些规则都记不住也可以省略不记,idea中alt+回车就完事了
2、lambda表达式举例:
刚开始入门的时候,你就先使用匿名内部类去写出来。因为这样子其实是会更方便你去理解代码,你理解代码之后,你后面就可以写的越来越快了
2.1:举例一
匿名内部类的写法: new Thread( new Runnable() { @Override public void run() { System.out.println("我其实很想靠近你"); } } ).start();- lambda简化:
new Thread(()->System.out.println("这是lambda表达式的简化形式")).start();
2.2:举例二
- 匿名内部类的写法:
@Test
public void Test02(){
int i = calculateNum(new IntBinaryOperator(){
public int applyAsInt(int left, int right){
return left + right;
}
});
System.out.println("i的值为:"+i);
}
public static int calculateNum(IntBinaryOperator operator){
int a = 60;
int b = 20;
return operator.applyAsInt(a,b);
}
- lambda简化:
@Test
public void Test02(){
int i = calculateNum((left, right) -> left + right);
System.out.println("i的值为:"+i);
}
public static int calculateNum(IntBinaryOperator operator){
int a = 60;
int b = 20;
return operator.applyAsInt(a,b);
}
2.3:举例三
@Test
public void Test04(){
printNum(new IntPredicate(){
public boolean test(int value){
return value %2 == 0;
}
});
}
public static void printNum(IntPredicate intPredicate){
int[] arr = {1,2,3,4,5,6,7,8,9,10};
for(int i : arr){
if(intPredicate.test(i)){
System.out.println(i);
}
}
}
@Test
public void Test05(){
printNum(value -> value % 2 == 0);
}
2.4:举例四:这个有意思
不管你的匿名内部类有多复杂,lambda表达式只关心你的参数列表和方法体!!
@Test
public void Test06(){
Integer result = typeConver(new Function<String,Integer>(){
public Integer apply(String str){
return Integer.valueOf(str);
}
});
}
public static <R> R typeConver(Function<String,R> function){
String str = "12345";
R result = function.apply(str);
return result;
}
@Test
public void Test07(){
Integer result = typeConver(str -> Integer.valueOf(str));
}