Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包(注意和数学传统意义上的不同)。(百度百科)
一、 lambda 怎么实现
先看一个例子
// 声明一个接口
public interface NoRetuenMultiParam {
void method(int a, int b);
}
// 普通实现
NoRetuenMultiParam retuenMultiParam = new NoRetuenMultiParam(){
@Override
public void method(int a, int b) {
System.err.println(a + b);
}
};
再使用lambda实现上述操作
NoRetuenMultiParam noRetuenMultiParam = (int a, int b) -> {
System.err.println(a + b);
};
// 发现什么了吗?
是不是更加的代码行数变少,更加简洁
1.1 lambda
首先简单记一下lambda表达式的语法形式
() -> {}
// 其中 () 用来描述参数列表,{} 用来描述方法体,-> 为 lambda 运算符 ,读作(goes to)。
- 那么lambda 表达式有什么要求呢?
- lambda 首先是一个匿名函数,而在Java中的匿名函数,只能出现在接口和抽象类中,那么lambda到底能用在那种类型里面呢?
测试一下:
- 声明一个抽象类
public abstract class TestAbstroout {
protected abstract void method(int i);
}
// 正常方式
TestAbstroout testAbstroout = new TestAbstroout(){
@Override
protected void method(int i) {
System.out.println(i);
}
};
// 简化为lambda方式
TestAbstroout test = (int i) -> {
System.out.println(i);
};
// 有错误提醒: The target type of this expression must be a functional interfaceJava(553648781)
//此类型必须是interface 类型
- 声明一个接口
public interface NoRetuenMultiParam {
void method(int a, int b);
}
//这个是可以的
NoRetuenMultiParam noRetuenMultiParam = (int a, int b) -> {
System.err.println(a + b);
};
// 声明一个有两个抽象方法的接口
public interface NoRetuenMultiParam {
void method(int a, int b);
void methods(int a);
}
// 使用的时候报错
通过上面的代码可以有一下几个总结
- lambda必须是一节接口类型的
- 接口中必须尤其只有一个未实现的方法
在Java8中有一个注解,@FunctionalInterface
表示该注解修饰的类只能有一个抽象方法,而这种形式更多的和lambda表达式一起使用, 当然也可以不实用次注解,但是必须保证只能有一个抽象方法
1.2 常见的lambda有那些
通过上述发现lambda的语法是()-> {}, ()是参数,{} 是方法体,并且它是针对方法的,那Java的方法有那些?
- 空参数 有/无返回值
- 有参数 有/无返回值
基本可以概括了哈
1.3 简化lambda
我们平时使用的lambda 可不是上述例子中那个多书写的啊,当然,lambda肯定是有简化方式的
//标准的
NoRetuenMultiParam noRetuenMultiParam = (int a, int b) -> {
System.err.println(a + b);
};
// 可以简化参数类型,但是必须全部简化
NoRetuenMultiParam mNoRetuenMultiParam = (a, b) -> {
System.err.println("简化lambda " + (a + b));
};
// 标准的
ReturnOneParam mReturnOneParam = (int a) -> {
return a + 2;
};
// 省略()
ReturnOneParam vReturnOneParam = a -> {
return a + 20;
};
//。。。
还有其他几种,总结起来就是:
- 简化参数类型,可以不写参数类型,但是必须所有参数都不写
- 简化参数小括号,如果只有一个参数则可以省略参数小括号
- 简化方法体大括号,如果方法条只有一条语句,则可以胜率方法体大括号
- 如果方法体只有一条语句,并且是 return 语句,则可以省略方法体大括号
二、 lambda的使用场景
- 引用表达式
ReturnOneParam vOneParam2 = a -> add(a);
/**
* 返回值类型,参数类型应保持一一致性
*
* @param a
* @return
*/
public static int add(int a) {
return a + 30;
}
- 构造方法使用
interface ItemCreatorConstruct {
Item getItem();
}
interface ItemCreatorParamsConstruct {
Item getItem(String name);
}
public class Example {
public static void main(String[] args) {
ItemCreatorConstruct itemCreatorConstruct = new ItemCreatorConstruct() {
@Override
public Item getItem() {
return new Item();
}
};
Item item = itemCreatorConstruct.getItem();
ItemCreatorConstruct itemCreatorConstruct2 = () -> new Item();
ItemCreatorParamsConstruct itemCreatorParamsConstruct = name -> new Item(name);
// 类名::new 的方式来实例化对象
ItemCreatorConstruct itemCreatorConstruct3 = Item::new;
}
}
- 创建线程
new Thread(() -> {
});
- 遍历集合
list.forEach{
(it) -> {
}
}
- 其他