Java之Lambda表达式
参考:
https://blog.csdn.net/weixin_50862876/article/details/108689721
https://blog.csdn.net/guangboo/article/details/18368393
简介
Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。
应用于编程语言可以更好地写出更简洁、更灵活的代码,表达能力更强(当然对于没学过的相关内容的开发者会产生一定的阅读困惑)
有很多主流的编程语言都支持Lamba表达式,如:C++11 Java Python JS
因为本人是在Java学习的过程中接触了Lamba表达式,所以本文只分析了Lambda在Java是如何简化开发的
为了能有一定的直观印象,下面简单列举几种语言的Lamba表达式示例
//C++
char s[]="Hello World!";
int uppercase = 0; //modified by the lambda
for_each(s, s+sizeof(s), [&uppercase] (char c) {
if (isupper(c))
uppercase++;
});
//Java
public void runable() {
new Thread(() -> System.out.println("It's a lambda function!")).start();
}
//JavaScript
$('#submit').on('click', function(){ functionbody. })
Java & Lambda Expression
lambda表达式是JAVA8中提供的一种新的特性,它支持JAVA也能进行简单的“函数式编程”。
函数式接口
是产生lambda表达式的“母体”,简单地说,函数式接口是接口里只包含一个抽象方法的接口
对于函数式接口,才可以用Lambda表达式来创建该接口的对象
如Runnable类
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
//@FunctionalInterface是java8中也提供的一个专用的注解,通过这个注解,可以确定是否是函数式接口
为什么要使用Lambda表达式
避免匿名内部类定义过多
匿名内部类如:
Runnable r = new Runnable() {
@Override
publick void run() {
System.out.println("hello");
}
}
这里我们没有定义先写一个Class 来实现Runnable的接口,然后再new;而是好像直接new了一个Runnable”对象“(我们知道接口是不能实例化的,所以只是看起来)
当我们回看匿名内部类的代码时,会发现很多地方是多余的,所以还可以再简洁一点
多余的地方比如:run(),因为Runnable接口内部只有这一个方法 完全可以省略 编译器一样可以知道这里是哪个方法的定义
new Runnable也可以省掉,只需要告诉编译器r是一个 Runnable
这里就可以引入Lambda表达式
Java8 中引入了一个新的操作符 “->” 该操作符称为箭头操作符或 Lambda 操作符,箭头操作符将 Lambda 表达式拆分成两部分 :
左侧 : Lambda 表达式的参数列表
右侧 : Lambda 表达式中所需执行的功能, 即 Lambda 体
所以改进为:
Runnable r;
r = ()->{System.out.println("hello")};
Lambda表达式还有其他的作用,但本人在开发中还未体会,因此暂时只列举这一项
Lambda表达式的语法
一 : 无参数,无返回值
() -> System.out.println(“Hello Lambda!”);
二 : 有一个参数,并且无返回值
(x) -> System.out.println(x)
三 : 若只有一个参数,小括号可以省略不写
x -> System.out.println(x)
Consumer con = (x) -> System. out .println(x);
con.accept( “啦啦啦,我是卖报的小行家” );
四 : 有两个以上的参数,有返回值,并且 Lambda 体中有多条语句
Comparator com = (x, y) -> {
System.out.println(“函数式接口”);
return Integer.compare(x, y);
};
五 : 若 Lambda 体中只有一条语句, return 和 大括号都可以省略不写
Comparator com = (x, y) -> Integer.compare(x, y);
六 : Lambda 表达式的参数列表的数据类型可以省略不写,因为JVM编译器通过上下文推断出,数据类型,即“类型推断”
(Integer x, Integer y) -> Integer.compare(x, y);
注 : Lambda 表达式中的参数类型都是由编译器推断得出的。 Lambda 表达式中无需指定类型,程序依然可以编译,这是因为 javac 根据程序的上下文,在后台推断出了参数的类型。 Lambda 表达式的类型依赖于上下文环境,是由编译器推断出来的。这就是所谓的 “类型推断”。