目录
前言
lambda表达式是Java8最受期待的新特性。接下来将从lambda表达式的作用,语法,原理,优缺点,以及一些demo来分析lambda表达式。
一、lambda是什么?
lambda表达式也叫闭包,lambda允许把函数作为参数传递到方法(把代码段作为方法的参数传递到方法中)。
用途:用于简化Java接口式的匿名内部类,集合的迭代,Stream操作,与函数式接口Predicate配合等等。文章主要介绍用于简化Java接口式的匿名内部类。
优点:1代码简洁 2. 不会生成class文件
缺点:降低了可读性
二、使用lambda表达式
1.函数式接口
函数式接口概念:只有一个抽象方法的接口。tip:不包含object中的方法,如toString()
//这个就是一个函数式接口
public interface Eatable {
public void eat();
}
2.lambda的例子
基本语法:(参数1,参数2,......)->{.....}
1.抽象方法无参数无返回值
接口
public interface People {
public void Runable();
}
- 定义一个测试类Lambdaclass,在测试类中提供两个方法
①、一个方法是:usePeople(People p)
②、一个方法是主方法,在主方法中调用usePeople方法
(1) 通过实现类的方法
//people实现类
public class PeopleImpl implements People{
@Override
public void Runable() {
System.out.println("我在跑步");
}
}
................
public class LambdaClass {
public static void main(String[] args) {
//普通
People people = new PeopleImpl();
usePeople(people);
}
private static void usePeople(People p){
p.Runable();
}
}
(2)匿名内部类
public class LambdaClass {
public static void main(String[] args) {
//匿名内部类
usePeople(new People() {
@Override
public void Runable() {
System.out.println("我在跑步1");
}
});
}
private static void usePeople(People p){
p.Runable();
}
}
(3)lambda表达式
public class LambdaClass {
public static void main(String[] args) {
//lambda表达式
usePeople(()->System.out.println("我在跑步2"));
}
private static void usePeople(People p){
p.Runable();
}
}
通过观察上面的实现方法比较,是不是lambda表达式的非常简洁呢?原来需要一个peopleimpl的一个实现类,使用lambda表达式只需要一个表达式就行了。
2.抽象方法带参无返回值
接口
public interface People {
public void Runable(String s);
}
还是和上面的一样
public class LambdaClass {
public static void main(String[] args) {
//lambda表达式
usePeople((String s)->{
System.out.println("我在跑步2");
System.out.println(s);
});
private static void usePeople(People p){
p.Runable("aa");
}
}
3.带参数带返回值
public interface People {
public String Runable(String s);
}
public class LambdaClass {
public static void main(String[] args) {
//lambda表达式
usePeople((String s)->{
System.out.println("我在跑步2");
System.out.println(s);
return s;
});
private static void usePeople(People p){
p.Runable("aa");
}
}
三.lambda表达式的简化
lambda表达式的基础用法和语法以及讲解完了,那它还有什么简化呢?当然有那就是----------方法的引用
格式:类名::方法名 或 对象名::方法名
还是以上面的demo为基础
public class LambdaClass {
public static void main(String[] args) {
//lambda表达式
usePeople((String s)->System.out.println(s));
//方法的引用
usePeople(System.out::println);
private static void usePeople(People p){
p.Runable("aa");
}
}
上面的
(String s)->System.out.println(s)和System.out::println 是一样的只是对lambda表达式进行了简化
再来看一个引用的例子: 相信有了这个例子之后,会对方法的引用理解的更加好
@FunctionalInterface
public interface Consumer<T> {
void accept(T var1);
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (t) -> {
this.accept(t);
after.accept(t);
};
}
}
public class LambdaClass {
public static void main(String[] args) {
Consumer<String> con = new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
};
con.accept("3333");
Consumer<String> con1 = s->System.out.println(s);
con1.accept("aaaa");
Consumer<String> con2 = System.out::println;
con2.accept("bbb");
}
四.lambda表达式的实现原理
public class InterfaceDemo {
//定义函数接口方法
public void hi(MyInterface myInterface){
myInterface.sayHi();
}
public static void main(String[] args) {
InterfaceDemo demo = new InterfaceDemo();
demo.hi(()-> System.out.println("我是lambda"));
}
编译之后
public class InterfaceDemo {
//定义函数接口方法
public void hi(MyInterface myInterface){
myInterface.sayHi();
}
//编译器自动添加静态方法,方便动态生成的内部类调用
private static void lambda$main$0(){
System.out.println("我是lambda");
}
public static void main(String[] args) {
//编译器动态创建的局部内部类
final class InterfaceDemo$$Lambda$14 implements MyInterface {
private InterfaceDemo$$Lambda$14() {
}
@LambdaForm.Hidden
public void sayHi() {
InterfaceDemo.lambda$main$0();
}
}
InterfaceDemo demo = new InterfaceDemo();
demo.hi(new InterfaceDemo$$Lambda$14());
}
由上面可知
1.jdk编译时使用时会给使用lambda表达式的类,添加一个私有,静态方法,格式:lambda$方法名$序号
2.动态创建一个局部内部类,该类实现了函数接口,重写函数接口唯一的抽象方法,局部内部类重写接口抽象方法
lambda表达式实际上是: 常规的接口实现,只是简化了代码。
总结
主要讲了lambda表达式的概念,基本语法和运用,以及方法引用,还有一些其它的用法和细节就不再赘述了。
有错误的地方欢迎指出
参考文章: