系列文章目录
第一章 JDK1.8 Lambda表达式
前言
有一说一,Lambda表达式是JDK1.8的最大亮点,使用它设计的代码会更加简洁。有幸在工作中,项目是使用JDK1.8,且代码实现都是使用Lambda表达式。如有遗漏的欢迎评论区补充讨论。
一、Lambda表达式是什么?
Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。
Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
使用 Lambda 表达式可以使代码变的更加简洁紧凑。
二、重要特征
可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定表达式返回了一个数值。
三、语法
lambda表达式由参数、箭头、表达式组成。
(parameters) -> expression //此处行为为表达式,这里隐含了return语句。
或者
(parameters) -> { statements; } //此处行为为语句,需要返回时要手写return语句。
1.使用大括号
如果代码无法在一个表达式中完成,可以像写方法一样把代码放在大括号中。只有一行代码的Lambda表达式也可以使用大括号
// a.一行表达式使用大括号{}
new Thread(() -> {
System.out.println("Lambda!");
});
// b.只有一行代码的大括号{}可以省略不写
new Thread(() -> System.out.println("Lambda!"));
// c.多行表达式使用大括号{}
new Thread(() -> {
System.out.println("Lambda!");
System.out.println("Lambda!");
});
等同于常规写法
// 上面的a和b
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Lambda!");
}
});
// 上面的c
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Lambda!");
System.out.println("Lambda!");
}
});
2.传参
没有参数时,也要提供一个空的小括号。如果只有一个参数,而且这个参数的类型可以推导,也可以省略小括号,Lambda表达式也可以包含多个参数
// a.没有参数时,也要提供一个空的小括号
NoReturnNoParamInterface noReturnNoParamInterface = () -> {
System.out.println("NoReturnNoParam");
};
// b.如果只有一个参数,而且这个参数的类型可以推导,也可以省略小括号
String text = "yeah";
NoReturnNoParamInterface noReturnNoParamInterface = (String text) -> {
System.out.println("NoReturnNoParam," + text);
};
NoReturnNoParamInterface noReturnNoParamInterface = text -> {
System.out.println("NoReturnNoParam," + text);
};
等同于常规写法
// 上面的a,NoReturnNoParamInterfaceImpl是具体实现
NoReturnNoParamInterface noReturnNoParamInterface = new NoReturnNoParamInterfaceImpl() {
@Override
public void test() {
System.out.println("NoReturnNoParam");
}
};
// 上面的b,NoReturnNoParamInterfaceImpl是具体实现
String text = "yeah";
NoReturnNoParamInterface noReturnNoParamInterface = new NoReturnNoParamInterfaceImpl(text) {
@Override
public void test(String text) {
System.out.println("NoReturnNoParam," + text);
}
};
3.遍历集合
List<String> list = new ArrayList<String>();
list.add("hello");
list.forEach(b -> {
System.out.println(b);
});
等同于常规写法
List<String> list = new ArrayList<String>();
list.add("hello");
for(String b : list){
System.out.println(b);
}
四、变量的作用域
lambda 表达式只能引用标记了final的外层局部变量,这就是说不能在 lambda 内部修改定义在域外的局部变量,否则会编译错误
参考菜鸟教程说明
public class Tester {
final static String startStr= "Hi! ";
public static void main(String args[]){
GetService getService = msg -> System.out.println(startStr+ msg );
greetService1.sayMsg("hxin");
}
interface GetService {
void sayMsg(String message);
}
}
输出结果为:
Hi! hxin
我们也可以直接在 lambda 表达式中访问外层的局部变量
public class Tester {
public static void main(String args[]) {
final int num = 2;
Converter<Integer, String> str = (param) -> System.out.println(String.valueOf(param + num));
str.convert(3);
}
public interface Converter<T1, T2> {
void convert(int i);
}
}
输出结果为:
5
lambda 表达式的局部变量可以不用声明为 final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义)
public class Tester {
public static void main(String args[]) {
int count = 1;
Converter<Integer, String> str = (param) -> System.out.println(String.valueOf(param + count));
str.convert(2);
count= 5;
}
public interface Converter<T1, T2> {
void convert(int i);
}
}
输出结果为:
// 报错
Local variable num defined in an enclosing scope must be final or effectively
在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量。
public class Tester {
public static void main(String args[]) {
int count = 1;
//编译会出错
Converter<Integer, String> str = (param, count) -> System.out.println(String.valueOf(param + count));
}
public interface Converter<T1, T2> {
void convert(int i);
}
}
原创,禁止转载!