目录
Lambda表达式
引例:实现接口
interface IMessage {
void printMessage(String msg);
}
class MessageImpl implements IMessage{
@Override
public void printMessage(String msg) {
System.out.println(msg);
}
}
public class LambdaTest {
public static void main(String[] args) {
IMessage message = new MessageImpl();
message.printMessage("正经用法");
}
}
//输出:正经用法
上面是最常见的用法,子类实现接口覆写抽象方法,然后定义子类对象,向上转型为父类对象。
假设此时具体的实现子类只会使用一次,那我们就没必要实现子类,于是我们使用匿名内部类来简化子类的实现:
public class LambdaTest {
public static void main(String[] args) {
IMessage message = new MessageImpl();
message.printMessage("正经用法");
//匿名内部类
IMessage message1 = new IMessage() {
@Override
public void printMessage(String msg) {
System.out.println(msg);
}
};
message1.printMessage("匿名内部类的用法");
}
}
//输出:匿名内部类的用法
圈住的部分就相当于class 没名字 implements Imessage { 覆写了printMessage方法; },可以看到,我们之间 new 的接口IMessage 的对象,将子类省略了,那么使用 Lambda 表达式还能进一步简化吗?
public class LambdaTest {
public static void main(String[] args) {
//Lambda 表达式
IMessage message2 = (msg) -> System.out.println(msg);
message.printMessage("Lambda表达式的用法");
}
}
//输出:Lambda表达式的用法
可以看到,Lmabda 表达式直接省略了所有和类相关的代码,new Imessage全都没了只保留了最核心的方法的代码,包括方法的参数,方法的方法体。
概念
是Lambda表达式(有的语言称为闭包) 是JDK1.8引入的重要特性-也是一-种编程范式函数式编程
面向对象的编程有个最大的问题,就是啥都得有个类,有个对象,通过对象去处理数据和方法
在大数据运算中,通常我们只需要关系特定的方法调用即可。
在Java中Lambda表达式的前身就是匿名内部类,就是匿名内部类的简化写法。
具体使用
Lambda表达式的语法
(参数列表) -> { //这里的参数和抽象方法的参数一致,
//若只有一行代码可以省略大括号,若有多行就不能省略
方法体代码
[return返回值];
} ;
使用要求
1. Lambda表达式一般都是结合接口来使用, 对于接口有一个要求, 该接口必须只能有一个抽象方法。因为Lambda表达式把方法名称都省了,因此默认就覆写那个唯一的抽象方法
@FunctionalInterface注解用在接口声明上,检查当前的接口是否只包含一个抽象方法。
在JDK1.8中对接口做了扩展,允许接口存在普通方法。普通方法使用default来声明,包含方法体。
@FunctionalInterface
interface IMessage {
void printMessage(String msg);
//普通方法,子类不一定需要覆写
default void test(){
System.out.println("这是一个普通方法");
}
}
class MessageImpl implements IMessage{
@Override
public void printMessage(String msg) {
System.out.println(msg);
}
}
public class LambdaTest {
public static void main(String[] args) {
MessageImpl message3 = new MessageImpl();
message3.test();
}
}
//输出:这是一个普通方法
可以看到,子类没有覆写接口的 test 方法依然可以成功调用它,因为它是一个普通方法
2. 参数类型可以省略,若省略了类型,则每个参数的类型都要省略。
3.若带返回值的方法只有一行代码,则可以省略return关键字和 {}
interface HasReturnParameter{
int test4();
}
public class LambdaUsage {
public static void main(String[] args) {
HasReturnParameter i3 = ()->10;
System.out.println(i3.test4());
}
}
//输出:10
接口的抽象方法的4种情况:
1.无返回值无参数
interface NonReturnNonParameter{
void test1();
}
public class LambdaUsage {
public static void main(String[] args) {
NonReturnNonParameter i1 = () -> {
System.out.println("无返回值无参数");
};
//也可写成:
// NonReturnNonParameter i1 = () -> System.out.println("无返回值无参数");
i1.test1();
}
}
//输出:无返回值无参数
Lambda表达式中的 ( ) 和接口的抽象方法中的 ( ) 对应,表示无参数,
大括号{ } 里面的是覆写后的方法代码,
最后 i1.test1( ); 调用的是我们刚刚覆写的方法
2.无返回值有参数
interface NonReturnHasParameter{
void test2(int age,String name);
}
public class LambdaUsage {
public static void main(String[] args) {
NonReturnHasParameter i2 = (age, name) ->{
age = age + 1;
name = "张三";
System.out.println(age + " " + name);
};
i2.test2(18,"");
}
}
//输出:19 张三
根据表达式的第二点使用要求,我们可以省略返回值类型,但是要省略就必须所有参数都省略。
3.有返回值无参数
interface HasReturnNonParameter{
int test4();
}
public class LambdaUsage {
public static void main(String[] args) {
HasReturnNonParameter i3 = ()->{
int a = 10;
return a;
};
}
}
4.有返回值有参数
interface HasReturnHasParameter{
int test(int age,String name);
}
public class LambdaUsage {
public static void main(String[] args) {
HasReturnHasParameter i4 = (t1,t2)->{
t1 = 20;
t2 = "Emily";
return t1;
};
}
}