Java新特性-Lambda表达式
  TEZNKK3IfmPf 2023年11月12日 22 0

创建一个线程实现类。

/**
* @author BNTang
*/
public class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("thread -> " + Thread.currentThread().getName() + "启动了");
}
}

实现方法有 ​​3​​ 种如下。

方式 1

通过编写实现类的方式来实现需求,如下。

/**
* @author BNTang
*/
public class TestMain {
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();

new Thread(myRunnable).start();
}
}

方式 2

通过匿名内部类的方式来实现,如下。

/**
* @author BNTang
*/
public class TestMain {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("thread -> " + Thread.currentThread().getName() + "启动了");
}
}).start();
}
}

方式 3

通过 Lambda 的方式来实现,如下。

/**
* @author BNTang
*/
public class TestMain {
public static void main(String[] args) {
new Thread(() -> {
System.out.println("thread -> " + Thread.currentThread().getName() + "启动了");
}).start();
}
}

Lambda 编写格式

(形式参数) -> {代码块}

  • ​形式参数​​​:如果有多个参数,参数之间用​​逗号​​ 隔开;如果没有参数,留空即可。
  • ​->​​​:由英文中画线和大于符号组成,​​固定写法​​。代表指向动作。
  • ​代码块​​:是我们具体要做的事情,也就是以前我们写的方法体中的内容。

组成 Lambda 表达式的三要素与使用要求,如下:

  • 形式参数
  • 箭头
  • 代码块

使用要求,如下:

使用 Lambda 表达式必须要有接口,并且要求接口中 ​​有且仅有​​ 一个抽象方法。

下面我将给出一个示例来看看吧,如下:

接口

/**
* @author BNTang
*/
public interface USB {
void work();
}

实现类

/**
* @author BNTang
*/
public class KeyBoardImpl implements USB {
@Override
public void work() {
System.out.println("键盘工作");
}
}

应用

/**
* @author BNTang
*/
public class TestMain {
public static void main(String[] args) {
USB keyBoard = new KeyBoardImpl();

mainBoard(keyBoard);
}

private static void mainBoard(USB usb) {
usb.work();
}
}

如上代码的含义很简单,就是普通的多态的写法,传入一个 USB 的实现类调用 work 方法进行处理。先来看看通过匿名内部类的方式怎么玩吧,如下:

/**
* @author BNTang
*/
public class TestMain {
public static void main(String[] args) {
mainBoard(new USB() {
@Override
public void work() {
System.out.println("鼠标");
}
});
}

private static void mainBoard(USB usb) {
usb.work();
}
}

在来看看通过 Lambda 表达式的方式来怎么玩吧,如下:

/**
* @author BNTang
*/
public class TestMain {
public static void main(String[] args) {
mainBoard(() -> {
System.out.println("打印机");
});
}

private static void mainBoard(USB usb) {
usb.work();
}
}

带参数形式的 Lambda 表达式。

一个参数

/**
* @author BNTang
*/
public interface TestTable {
void fly(String s);
}

匿名内部类的方式如下:

/**
* @author BNTang
*/
public class FlyableDemo {

public static void main(String[] args) {
useTestTable(new TestTable() {
@Override
public void fly(String s) {
System.out.println(s);
}
});
}

private static void useTestTable(TestTable testTable){
testTable.fly("一个参数");
}
}

Lambda 表达式的方式如下:

/**
* @author BNTang
*/
public class FlyableDemo {

public static void main(String[] args) {
useTestTable((String s) -> {
System.out.println(s);
});
}

private static void useTestTable(TestTable testTable) {
testTable.fly("一个参数");
}

}

多个参数

/**
* @author BNTang
*/
public interface Addable {
int add(int x, int y);
}
/**
* @author BNTang
*/
public class AddableMain {
public static void main(String[] args) {
useAddable((int x, int y) -> {
return x + y;
});
}

private static void useAddable(Addable addable) {
int sum = addable.add(10, 20);
System.out.println(sum);
}
}

Lambda 表达式的省略模式

参数的类型可以省略

Java新特性-Lambda表达式

有多个参数的情况下,不能只省略一个,要么就全部省略不要一个省略一个不省略。

如果参数有且仅有一个,那么小括号可以省略,如下。

Java新特性-Lambda表达式

如果代码块的语句只有一条,可以省略大括号和分号,如下。

Java新特性-Lambda表达式

如果代码块的语句只有一条,可以省略大括号和分号,如果有 ​​return​​​,​​return​​ 也可以省略掉。

Java新特性-Lambda表达式

Lambda 表达式的注意事项

使用 Lambda 必须要有接口,并且要求接口中 ​​有且仅有​​ 一个抽象方法。

必须要有上下文环境,才能推导出 Lambda 对应的接口。

/**
* @author BNTang
*/
public class TestMain {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("匿名内部类");
}
}).start();
}
}

可以直接写,因为知道对应的接口是 ​​Runnable​​。

/**
* @author BNTang
*/
public class TestMain {
public static void main(String[] args) {
new Runnable() {
@Override
public void run() {
System.out.println("匿名内部类");
}
}.run();
}
}

直接这样写会报错,因为没有办法推导出对应的接口。

Java新特性-Lambda表达式

Lambda 表达式与匿名内部类的区别

所需的类型不同

匿名内部类:可以是接口,也可以是抽象类,还可以是具体类。

Lambda 表达式:只能是接口。

使用的限制不同

如果接口中 ​​有且仅有​​ 一个抽象方法,可以使用 Lambda 表达式,也可以使用匿名内部类。

如果接口中有多于的一个抽象方法,只能使用匿名内部类,而不能使用 Lambda 表达式。

实现的原理不同

匿名内部类:编译之后,会产生一个单独的 ​​.class​​ 字节码文件。

Lambda 表达式:编译之后,没有一个单独的 ​​.class​​ 字节码文件。对应的字节码会在运行的时候动态生成。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月12日 0

暂无评论

推荐阅读
  TEZNKK3IfmPf   23天前   51   0   0 java
  TEZNKK3IfmPf   2024年05月31日   55   0   0 java
TEZNKK3IfmPf