一、前言
- Lambda表达式是在Java8中引入的,并号称是Java8的最大的特点.
- Lambda表达式有利于函数式编程,简化了开发了很多。
- 允许把函数作为一个方法的参数(函数作为参数传递进方法中)
- λ表达式本质上是一个匿名方法
二、Lambda表达式语法
2.1
语法
(paramaters) -> expression(表达式)
(paramaters) -> statement(语句)
(paramaters) -> {expression/statement;}
2.2
特征
- (1)、可选类型声明 – 无需声明参数的类型。编译器可以从该参数的值推断。
- (2)、可选圆括号参数 – 无需在括号中声明参数。对于多个参数,括号是必需的。
- (3)、可选大括号 – 表达式主体没有必要使用大括号,如果主体中含有一个单独的语句。
- (4)、可选return关键字 – 编译器会自动返回值,如果主体有一个表达式返回的值。花括号是必需的,以表明表达式返回一个值。
2.3
例子
public int addition(int a, int b) {return a + b;}
//lambda表达式写法1
(int a, int b) -> a + b
//lambda表达式写法2
(int a, int b) -> { return a + b; }
//lambda表达式写法3 (自动推断参数类型)
(a, b) -> a + b;
- lambda公式:
(参数列表) -> { 表达式; }
2.4
Lambda的类型
2.4.1
λ表达式返回值类型是的目标类型,目标类型是”函数接口(functional interface)”函数接口
:一个只含有显式声明的抽象方法的接口。public interface Runnable {void run();} public interface Comparator<T> { int compare(T o1, T o2); boolean equals(Object obj); }
- 注:第二个接口也是函数接口,因为equals方法是Object的,
所有的接口都会声明Object的public方法——虽然大多是隐式的,只不过Comparator 显式的声明了equals
2.4.2
用Lambda表达式赋值可以用一个λ表达式为一个函数接口赋值:
//(1) Runnable r1 = () -> { System.out.println("Lambda!");}; Object obj = r1; //(2)错误例子 Object obj = () -> {System.out.println("Lambda!");}; //错误:对象不是函数接口! //(3)必须显式的转型成一个函数接口才可以 Object obj = (Runnable)()->System.out.println("Lambda!");};
λ表达式只有在转型成一个函数接口后才能被当做Object使用
System.out.println( () -> {} ); //错误! 目标类型不明 System.out.println( (Runnable)() -> {} ); // 正确
自定义函数接口
@FunctionalInterface public interface MyFuntionInterface { public void doSomething(); } Runnable r1 = ()->{System.out.println("Runnbale");}; MyFuntionInterface m2 = ()->{System.out.println("MyFI");}
- 都是正确的写法。这说明一个λ表达式可以有多个目标类型(函数接口), 只要函数匹配成功即可。但需注意一个λ表达式必须至少有一个目标类型*/
三、Lambda表达式的用处
(1)、
用于替换以前广泛使用的内部匿名类
内部匿名类写法
Thread t1 = new Thread (new Runnable(){ @Override public void run() { System.out.println("匿名内部类写法"); } }
Lambda表达式写法
Thread t2 = new Thread( ()->{System.out.println("Lambdas'");} );
- 注意:第2个线程里的λ表达式,你并不需要显式地把它转成一个Runnable,因为Java能根据上下文自动推断出来:一个Thread的构造函数接受一个Runnable参数,而传入的λ表达式正好符合其run()函数,所以Java编译器推断它为Runnable
(2)、
λ表达式与集合类批处理操作(或者叫块操作)
集合类的迭代分为
List<String> list = new ArrayList<>() {"AA", "BB", "CC"};
外部迭代:由客户代码进行迭代
for(Object o : list) { // 外部迭代 System.out.println(o); }
内部迭代:由Java类库来进行迭代
list.forEach( o -> {System.out.println(o);} );
-
forEach
方法接受一个函数接口Consumer做参数,故可以使用λ表达式
-