【【0003】java中关于匿名表达式与lambda表达式关系的理解:
今天下午看代码,有一块写不出来了,我知道那是lambda表达式代码进行简化代码,但是自己去写简化代码又忘了怎么写的了,出现了报错,所以去查了一些以前的笔记和网上资料,写个博客记录一下:
/*未进行lambda的匿名表达式*/
Set apples = new TreeSet<>(new Comparator() {
public int compare(Apple o1, Apple o2) {
return Double.compare(o2.getPrice(), o1.getPrice());//降序
}
});
/*进行lambda之后的表达式未完全版本*/
Set apples1 = new TreeSet<>((Apple o1, Apple o2) -> {
return Double.compare(o2.getPrice(), o1.getPrice());
});
/*进行lambda之后的表达式完全版本,也是我出错的地方,
我对去掉return不理解,去掉花括号就报错,不去掉做不到最简化,因为毕竟就一句话,是可以去掉花括号的*/
Set apples2 = new TreeSet<>((o1, o2) -> Double.compare(o2.getPrice(), o1.getPrice()));
/* 我疑惑为啥可以去掉return,后来想想他连返回值类型都省略了,return省略也是合情合理
* 难免让我想到C语言对函数返回值的理解,因为函数结束,无返回值其实是也是有返回值的,
* 那是给进程看的,提示这个方法体结束了,在看idea对lambda之后的表达式未完全版本是用灰色表示的,说明return没必要
* 以上是我对lambda省略的理解,*/
Lambda表达式函数式是一个可传递的代码块,可以在以后执行一次或多次。采用支持函数式编程的思想(把函数作为参数传递给另一个函数),对函数式接口(只包含唯一一个抽象方法的接口),通过Lambda表达式来创建该接口的对象。
语法:参数 箭头(->) 表达式
例如:
第一个lambda表达式(代码块为first.length-second.length):
(String first, String second)->first.length()-second.length()
函数式接口:一个:只有一个方法
唯一:只能是抽象方法(接口可以声明Object的非抽象方法让方法不再抽象例如:toString)
1.更加简化匿名内部类(一个类在另一个类中定义,创建这个类的对象只是用一次,且没有名字);
2.对使用匿名内部类代码中只保留核心逻辑,看着舒服;
3.当然还有对函数式接口实现的接话,线程的实现的简化等等简化代码量,本篇主要记录和匿名表达式的相关的简化;
4.如果对匿名内部类不是很了解,可以参考一下这篇博客:
https://blog.csdn.net/qq_35394434/article/details/111695348
public class Test123 {
public static void main(String[] args) {
Heihei2 heihei = new Heihei2();
heihei.function();
}
}
interface Heihei1 {
void function();
}
class Heihei2 implements Heihei1 {
@Override
public void function() {
System.out.println("实现功能成功1");
public static void main(String[] args) {
Heihei1 heihei = new Heihei1() {
@Override
public void function() {
System.out.println("实现功能成功1");
}
};//用分号结束
heihei.function();
}
}
interface Heihei1 {
void function();
}
匿名类是没有类名称的,当然也可以这么写:(类名.方法名)
public static void main(String[] args) {
new Heihei1() {
@Override
public void function() {
System.out.println("实现功能成功1");
}
}.function();
}
}
interface Heihei1 {
void function();
}
其中匿名类为:
new Heihei1() {
@Override
public void function() {
System.out.println("实现功能成功1");
}
}
是否使用匿名表达式区别:可以看出匿名类需要在定义时就实例化成对象,简化了通过实现类然后再实例化成对象的过程,代码量更少!
自由变量的值:外围作用域的值,但不能是可变变量,必须是最终变量,因为可变变量容易引发lambda表达式并发执行造成不安全;
public static void main(String[] args) {
/*一个表达式*/
Heihei1 heihei = ()-> System.out.println("实现功能成功1");
/*多个表达式
Heihei1 heihei = ()-> {System.out.println("实现功能成功1");
System.out.println("实现功能成功1");
}
*/
heihei.function();
}
}
interface Heihei1 {
void function();
}
是否使用lambda表达式区别:可以看出lambda表达式后的代码在定义和实例化上都进行了简化代码的规则,代码量更少!
该情况语法:
() 箭头(->)一个表达式;//无参()内就啥都不写,但必须保留()
例如:
(String first)->first.length()-1//省略{}
( first)->first.length()-1//省略参数类型和{}
first->first.length()-1//省略参数类型、()和{}
该情况语法:
(参数) 箭头(->)一个表达式;//如果lambda表达式能够推断出参数类型,可以省略写参数
/*一个表达式*/
(String first,String second)->{first.length()-second.length();}
( first,second)->first.length()-second.length()//省略参数类型和{}
/*多个表达式*/
(String first,String second)->{first.length()-1;second.length()-1;}
( first, second)->{first.length()-1;second.length()-1;}//省略参数类型
该情况语法:
(参数) 箭头(->){第一个表达式;第二个表达式}//如果lambda表达式能够推断出参数类型,可以省略写参数类型
1.以上就已经算关于匿名表达式的lambda表达式的浅解,然后了解更多,会学习到关于函数接口对lambda表达式的理解,java新增的这个特性好像性就是为解决函数式编程而产生的,
2.就比如:
要使用Arrays.sort();需要传入函数式接口类型的对象,而lambda表达式可以转化为函数式接口(将其看做一个函数,返回一个函数式接口类型的对象)而通过**传统的去先定义接口,再定义实现类,再创建对象才能使用,lambda表达式就显得无比简化了步骤:(和上面的匿名表达式在省略步骤作用很相似)
Arrays.sort(word,(first,second)->first.length()-second.length());
1.ambda表达式是不需要指出返回值类型的,它的返回类型总是会由上下文推到得出;(方法体中如果只有一条return语句,那么大括号可以省略,且去掉return),这个是我开始不理解的地方,上网课看视频没有提到的点;
2.ambda表达式怎么简化代码,只需要关注两点:参数个数和方法体内表达式个数:(第一点:参数的只有一个参数,那么小括号可以省略;第二点:方法体当中只有一句代码,大括号可以省略),至于参数类型要不要写,lambda表达式会推断出参数类型,可以不写;
3.匿名内部类多用于实现时间监听器和其他回调,lambda的使用可以说取代了匿名表达式的作用,更加简洁,然而了解了更多发现,lambda表达式的用处不仅仅在于匿名表达式的简化,也有处理线程的实现,函数式接口的运用等等,以后遇到了在进行总结吧,有问题欢迎补充哦!