上篇描述了两种关于线程的创建与启动,在写最后一种线程的创建启动前先把Lambda表达式复习一下
Lambda表达式是java 8 的新特性,支持将代码块作为某一方法的参数,允许使用更简洁的代码来创建只有一个抽象方法的接口的实例,接口统称为函数式接口
该表达式的作用是代替匿名内部类的烦琐语法,组成部分为一下三个
- 形参列表 允许省略形参类型,当只有一个参数时,形参列表的圆括号可以省略
- 箭头( ->) 英文中划线以及大于符号
- 代码块 也是最主要的组成部分 若代码块只包含一条语句,则代码块的花括号允许被省略,语句就不需要花括号表示语句结束. 当代码块只有一条return 语句时,可以省略return 关键字,表达式需要返回值,而代码块中仅有一条省略了return语句,表达式则会自动返回语句的值
下面举三个例子对组成部分进行解读
一、当代码块只有一条执行语句时 省略花括号
interface One { void oneTest(); }
public class TestClazz{
//以 One对象作为参数的方法
public void oneTest(One oneName){
System.out.println("测试One==" + oneName);
oneName.oneTest();
}
public static void main(String[] args){
TestClazz testClazz = new TestClazz();
//测试一
// testClazz.oneTest(new One() {
// @Override
// public void oneTest() {
// System.out.println("测试一结果");
// }
// });
//上方代码可简化成
//当代码块只有一条执行语句时 省略花括号
testClazz.oneTest(() -> System.out.println("测试一结果"));
}
二、形参只有一个时可以将圆括号去掉
interface Two { void twoTest(String str); }
public class TestClazz{
//以 Two 对象作为方法参数
public void twoTest(Two two){
System.out.println("测试二="+two);
two.twoTest("测试二");
}
public static void main(String[] args){
TestClazz testClazz = new TestClazz();
// testClazz.twoTest(new Two() {
// @Override
// public void twoTest(String str) {
// System.out.println(str);
// System.out.println("测试二结果");
// }
// });
//上方代码可简化成
//形参只有一个时可以将圆括号去掉
testClazz.twoTest(str -> {
System.out.println(str);
System.out.println("测试二");
});
}
}
三、表达式内代码块只有一条语句,花括号可以省略,即使该表达式需要返回值,可将return关键字省略
interface Third { BigDecimal thirdTest(BigDecimal a , BigDecimal b); }
public class TestClazz{
public void thirdTest(Third third) throws Exception{
System.out.println("a * b 结果为 =" + third.thirdTest(new BigDecimal("50"),new BigDecimal("30")));
}
public static void main(String[] args) throws Exception{
TestClazz testClazz = new TestClazz();
//
// testClazz.thirdTest(new Third() {
// @Override
// public BigDecimal thirdTest(BigDecimal a, BigDecimal b) {
// return a.multiply(b).setScale(2,BigDecimal.ROUND_DOWN);
// }
// });
//上方代码可简化成
///表达式内代码块只有一条语句,花括号可以省略,即使该表达式需要返回值,可将return关键字省略
testClazz.thirdTest((a ,b) -> a.multiply(b).setScale(2,BigDecimal.ROUND_DOWN));
}
}
上述TestClazz中调用的三个不同的方法都需要不同类型的参数,但使用Lambda表达式后所有参数都为该表达式,而且能正常被编译、执行,即表达式会被当成一个当前方法所需要的参数类型的 类型. 下一篇将介绍表达式被当成何种对象