一看就懂:Java 之 Lamda 写法

概述

现在,很多同学已经接受并熟悉了 Java 的 Lamda 写法,但可能有些同学还是一头雾水。
这里,我抛砖引玉,来对 Java Lamda 写法做一个简单的介绍:

  • 首先 Lamda 写法的固定格式为:参数 -> 语句块

  • 另外 Lamda 语法是出现在Java8及其以后的,Java8以前是不涉及的,所以JDK1.7及其以前版本这种写法编译是会被报错的。

优势

那么Lamda 写法有哪些优势呢?

  • 首先,他简化了代码,将以前很多行的代码简化为几行或者一行,使得代码看上去更加的简介;

  • 另外,Lamda 算法对并行运算非常具有优势,某些实现用 Lamda 方式会更加高效。

示例

如果一个接口只有一个实现方法,我们称这种接口叫做函数式接口。
那么我们通常会以匿名内部类的方式去实现。

比如:我们常用的多线程去异步实现某个功能的时候,常常会使用如下方式:

new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("异步功能实现");
    }
}).start();

这里的 Runable 接口就一个run() 实现方法,源码如下图:
在这里插入图片描述

那么这种条件下,就可以简化为 Lamda 写法,具体效果如下:

new Thread(() -> System.out.println("异步实现功能")).start();

我们可以看见:Lamda 写法的代码量已经浓缩为了一行,确实简洁了不少。

释义

那么如何理解上面这句 Lamda 写法呢?

(1)我们可以看到,变化的只是参数接口匿名实现类的写法,外面外并未有任何变化;

(2)由于 Thread 类里面就一个以接口为参数的方法,所以省去了接口名 Runable;

(3)由于 Ruanble 接口里面就一个 run() 方法定义,故而省去了方法名;

(4)由于 run() 方法定义里未有任何参数,故而 Lamda 写法就只有以一个 () 开头了;

(5) 中间的箭头 -> 是 Lamda 标识符,读作 “goes to”;

(6)箭头后面就是实现方式了,这个同以前代码实现。

拓展示例

示例1

那么,当一个接口的唯一方法涉及多个参数,此时 Lamda 写法又该怎么样呢?

我们不妨创建一个 MyService,里面包含一个带有参数的方法定义:

public  interface MyService {

	public void say(String name);

}

然后我们创建一个 Test 类,并在类里面添加一个该接口为参数的 test() 方法,以及主方法进行测试:

Java 8 以前的写法:

public class Test {

    public static void main(String[] args){
        test(new MyService() {
            @Override
            public void say(String name) {
                System.out.println("hello : " + name);
            }
        });
    }
    
    public static void test(MyService service) {
        service.say("jack");
    } 

}

程序运行结果为如下所示:

在这里插入图片描述

Java 8 Lamda 写法:

public class Test {

    public static void main(String[] args){
        test((name) -> System.out.println("hello : " + name));
    }
    
    public static void test(MyService service) {
        service.say("jack");
    } 

}

运行结果,同样为:
在这里插入图片描述

经过上面两个例子,我们已经证实了,两种写法的运行效果完全是可以等价的,Lamda 写法看起来也更简洁。

另外,当参数只有一个的时候,参数的括号也可以省去不写,例如,上面的 Lamda 写法还可以进一步简写:

test(name -> System.out.println("hello : " + name));

同理,如果接口的方法有多个参数的时候,Lamda 参数括号里也需要传递多个参数。

示例2

我们将接口里面的 say(String name) 方法,增加一个参数 age,改为如下:

public interface MyService {

    public void say(String name, int age);

}

那么对应的方法调用就成为了如下:

Java 8 前写法:

public class Test {

	public static void main(String[] args){
		test(new MyService() {
			@Override
			public void say(String name, int age) {
				System.out.println("hello : " + name + ", I am " + age);
			}
		});
	}
	
	public static void test(MyService service) {
		service.say("jack", 28);
	} 

}

Java 8 Lamda 写法:

public class Test {

	public static void main(String[] args){
		test((name, age) -> System.out.println("hello : " + name + ", I am " + age));
	}
	
	public static void test(MyService service) {
		service.say("jack", 28);
	} 

}

两种写法的输出结果都是:
在这里插入图片描述

可以看到,随着接口方法 say() 里的参数增加,Lamda 参数括号里面的参数也相应增加。

同理,当 Lamda 语句块里面只有一条语句的时候,我们可以通常省略语句块符号{},如上面的 Lamda语句:

test((name, age) -> System.out.println("hello : " + name + ", I am " + age));

但如果涉及多条语句的时候,就需要增加语句块 {}了,比如我们将 name 和 age 分别打印的话,则对应的 Lamda 写法为:

test((name, age) -> {
	System.out.println("My name is"+ name);
	System.out.println("I am "+ age);
});

变量作用域

方法变量

首先,Lamda 语句中引用外层方法中的变量的时候,是不允许修改其变量值的,具体什么意思呢?我们不妨接着往下看。

我们在上一步中的方法增加一个变量;
在这里插入图片描述
然后我们在 Lamda 语句块中将其值修改下:
在这里插入图片描述
可以看到:编译器这时候报了错,说明其值是不允许被修改的:

这就说明: Lamda 不允许修改所在外层方法里的变量;

类变量

然后,我们将变量的位置挪动下,将方法变量移动到为类的变量(这里由于方法是 static 的,所以我们为了能直接访问到变量,也加上 static 修饰)。
在这里插入图片描述
可以看到,这时编译器并未进行报错,说明 Lamda 语句块中是可以修改其类成员变量(final 修饰除外)。

我们运行程序:
在这里插入图片描述
可以看到,确实是我们修改后的值。

结尾语

上面所讲的主要是 Lamda 写法之匿名内部类,这是一个较为容易理解 Lamda 写法的入门,谢谢大家!

【为什么还需要学习C++?】 你是否接触很多语言,但从来没有了解过编程语言的本质? 你是否想成为一名资深开发人员,想开发别人做不了的高性能程序? 你是否经常想要窥探大型企业级开发工程的思路,但苦于没有基础只能望洋兴叹?   那么C++就是你个人能力提升,职业之路进阶的不二之选。 【课程特色】 1.课程共19大章节,239课时内容,涵盖数据结构、函数、类、指针、标准库全部知识体系。 2.带你从知识与思想的层面从0构建C++知识框架,分析大型项目实践思路,为你打下坚实的基础。 3.李宁老师结合4大国外顶级C++著作的精华为大家推出的《征服C++11》课程。 【学完后我将达到什么水平?】 1.对C++的各个知识能够熟练配置、开发、部署; 2.吊打一切关于C++的笔试面试题; 3.面向物联网的“嵌入式”和面向大型化的“分布式”开发,掌握职业钥匙,把握行业先机。 【面向人群】 1.希望一站式快速入门的C++初学者; 2.希望快速学习 C++、掌握编程要义、修炼内功的开发者; 3.有志于挑战更高级的开发项目,成为资深开发的工程师。 【课程设计】 本课程包含3大模块 基础篇 本篇主要讲解c++的基础概念,包含数据类型、运算符等基本语法,数组、指针、字符串等基本词法,循环、函数、类等基本句法等。 进阶篇 本篇主要讲解编程中常用的一些技能,包含类的高级技术、类的继承、编译链接和命名空间等。 提升篇: 本篇可以帮助学员更加高效的进行c++开发,其中包含类型转换、文件操作、异常处理、代码重用等内容。
©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页