Java-Lambda表达式第一篇认识Lambda表达式
1、Lambda表达式时Java 8新增的特性。Lambda表达式支持将代码块作为方法参数,Lambda表达式允许使用更简洁的代码创建只有一个抽象方法的接口(即函数式接口)的实例。
2、当使用Lambda表达式代替匿名内部类创建对象时,Lambda表达式的代码块会代替实现抽象方法的方法体,Lambda表达式就相当于一个匿名方法。Lambda表达式由3部分组成:
1》形参列表:形参列表允许省略形参类型。如果形参列表中只有一个参数,甚至连形参列表的圆括号也可以省略。
2》箭头(->):必须通过英文中画线和大于号组成。
3》代码块:如果代码块只包含一条语句,Lambda表达式允许省略代码块的花括号。Lambda代码块只有一条return语句,甚至可以省略return关键字。Lambda表达式需要返回值,而它的代码块中仅有一条省略了return的语句,Lambda表达式会自动返回这条语句的值。
3、Lambda表达式与函数式接口
Lambda表达式的类型,也被称为“目标类型(target type)”,Lambda表达式的目标类型必须是函数式接口。函数式接口可以包含多个默认方法、类方法,但只能声明一个抽象方法。
Java 8专门为函数式接口提供了@FunctionalInterface注解,该注解通常放在接口定义前面,该注解对程序功能没有任何作用,只是告诉编译器要更严格的检查该定义的接口是否满足函数式接口的要求,即只包含一个抽象方法,否则编译器报错。
//Runnable是Java本身提供的函数式接口 //Lambda表达式的结果被当成一个对象 //使用Lambda表达式赋值 Runnable rn=() -> { for(int i=0;i<100;i++){ System.out.println("这里是run()方法体."); } };
从上面的实现可知,Lambda表达式实现的是一个匿名方法。Lambda表达式的局限性:
1》Lambda表达式的目标类型必须是明确的函数式接口。
2》Lambda表达式只能为函数式接口创建对象。Lambda表达式只能实现一个方法,因此它只能为一个抽象方法的接口(函数式)接口创建对象。
如果上面的代码赋值给Object类型,由于Object类不是明确的函数式接口,编译过程会报错“不是函数接口”。
4、方法引用和构造器引用
前面已经提到,如果Lambda表达式的代码块只有一条语句,可以省略花括弧,其实还可以在代码中使用方法引用和构造器引用。方法引用和构造器引用可以让Lambda表达式的代码块更加简洁。方法引用和构造器引用都需要使用两个英文冒号(::)。
Lambda表达式支持的方法引用和构造器引用
种类 | 示例 | 说明 | 对应的Lambda表达式 |
引用类方法 | 类名::类方法 | 函数式接口中被实现的全部参数传递给该类方法作为参数 | (a,b,...)->类名.类方法(a,b,...) |
引用特定对象的实例方法 | 特定对象::实例方法 | 函数式接口中被实现方法的全部参数传给该方法作为参数 | (a,b,...)->特定对象.实例方法(a,b,...) |
引用某类对象的实例方法 | 类名::实例方法 | 函数式接口中被实现方法的第一个参数作为调用者,后面的参数全部传给该方法作为参数 | (a,b,...)->a.实例方法(b,...) |
引用构造器 | 类名::new | 函数式接口中被实现方法的全部参数传递给该构造器作为参数 | (a,b,...)->new 类名(a,b,...) |
1》引用类方法:
@FunctionalInterface public interface Converter{ Integer convert(String from); } ... //创建一个匿名对象 Converter converter1= from -> Integer.valueOf(from); Integer val=converterl.convert("99"); System.out.println(val); ------------------------ Converter converter1= Integer::valueOf;
2》引用特定对象的实例方法
@FunctionalInterface public interface Converter{ Integer convert(String from); } ... //创建一个匿名对象 Converter converter1= from -> "hello".indexOf(from); Integer val=converterl.convert("ll"); System.out.println(val); ------------------------ Converter converter1= "hello"::indexOf;