从匿名内部类引入Lambda表达式
在线程池那篇博客中,我们通过使用匿名内部类来作为参数传入submit方法中。
但是我们发现,这样虽然在步骤上简单了许多,但是在空间上看着并不简单,甚至显得比较复杂。
那我们就用更简单的lambda表达式来代替匿名内部类。
package executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Demo2 {
public static void main(String[] args) {
ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(5);
newFixedThreadPool.submit(new Runnable() {
@Override
public void run() {
System.out.println("未自定义runnable接口实现类"+Thread.currentThread().getName());
}
});
newFixedThreadPool.submit(() ->
{
System.out.println("未自定义runnable接口实现类"+Thread.currentThread().getName());
});
newFixedThreadPool.submit(()->System.out.println("未自定义runnable接口实现类"+Thread.currentThread().getName()));
newFixedThreadPool.submit(()->System.out.println("未自定义runnable接口实现类"+Thread.currentThread().getName()));
newFixedThreadPool.submit(()->System.out.println("未自定义runnable接口实现类"+Thread.currentThread().getName()));
}
}
Lambda表达式
思想 "说重点"
lambda表达式的核心即在于说重点
以线程代码为例,他需要的是什么?最核心的东西是什么?
就是run方法!!!
runnable接口中重写实现的就一个run方法!!!接口只是run方法的载体,装黄桃的罐头盒子!!!核心只要run方法。
我们为什么要写runnable接口的实现类?就是为了重写run方法,并且让线程去执行run方法。
所以,现在我们不要盒子了,直接用手抓着吃!!!
service.submit(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
});
/*
匿名内部类方式来作为线程池执行目标代码
1. 这个方法需要的参数是Runnable接口的实现类对象
2. Runnable接口目标是为了提供一个run 方法, What will be run
3. What will be run??? where??? run方法内容
这里需要Runnable提供Run方法,提供Run方法方法体
"说重点"
需要Run方法方法体
*/
Lambda表达式格式
service.submit(() -> System.out.println(Thread.currentThread().getName()));
() -> System.out.println(Thread.currentThread().getName())
Lambda表达式
() 参数列表
-> 做什么事情,就是对应方法体
箭头之后的代码就是正常语句
(参数列表) -> {代码语句}
Lambda表达式使用,无参数无返回值
package com.qfedu.c_lambda;
/*
* 无参数无返回值
*/
interface Cook {
void cooking();
}
public class Demo1 {
public static void main(String[] args) {
invokeCook(new Cook() {
@Override
public void cooking() {
System.out.println("麻辣香锅,孜然肉片,土豆牛肉,蒜薹肉丝");
}
});
invokeCook(() -> {
System.out.println("蒜蓉油麦菜,番茄鸡蛋");
});
invokeCook(() -> System.out.println("明天早上自己炸油条"));
}
/**
* 执行Cook实现类对象方法
*
* @param cook Cook接口的实现类对象
*/
public static void invokeCook(Cook cook) {
cook.cooking();
}
}
Lambda表达式使用,有参数有返回值
这里面用到了Arrays.sort方法
后边是comparator接口 比较器实现
package com.qfedu.c_lambda;
import java.util.Arrays;
import java.util.Comparator;
public class Demo2 {
public static void main(String[] args) {
Person[] persons = {
new Person("骚磊", 16),
new Person("老黑", 50),
new Person("老付", 40),
new Person("污云", 35),
new Person("朋朋", 14),
new Person("大哥", 18),
};
// public static <T> void sort(T[] a, Comparator<? super T> c)
Arrays.sort(persons, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o1.getAge() - o2.getAge();
}
});
/*
* 1. 有参数
* 2. 有返回值
*
* (Person o1, Person o2) -> {
* return o1.getAge() - o2.getAge();
* }
* 标准Lambda
*/
Arrays.sort(persons, (Person o1, Person o2) -> {
return o2.getAge() - o1.getAge();
});
/*
* 1. 这里可以省略数据类型
* 2. 可以直接利用返回值,{}和return都省了掉
*/
Arrays.sort(persons, (o1, o2) -> o2.getAge() - o1.getAge());
for (Person person : persons) {
System.out.println(person);
}
}
}
甚至还可以更加简化,省略数据类型,但最好不要
package com.qfedu.c_lambda;
interface A {
float add(int num1, float num2);
}
public class Demo3 {
public static void main(String[] args) {
System.out.println(new A() {
@Override
public float add(int num1, float num2) {
return num1 + num2;
}
}.add(5, 13.5F));
/*
* 1. 数据类型真的可以省略,虽然是不同数据类型,Java语言真香
* 2. 实现的代码非一行,可以在大括号内完成你的目标
*/
test(5, 13.5F, (num1, num2) -> {
float sum = num1 + num2;
return sum;
});
}
public static void test(int num1, float num2, A a) {
System.out.println(a.add(num1, num2));
}
}
Lambda表达式使用前提
-
有且只有一个缺省属性为public abstract方法的接口,例如 Comparator接口,Runnable接口
扫描二维码关注公众号,回复: 9808550 查看本文章 -
使用lambda表达式是有一个前后要求约束的方法的参数为接口类型,或者说局部变量使用调用方法,可以使用lambda也OK
-
有且只有一个抽象方法的接口,称之为【函数式接口】Comparator接口,Runnable接口