1.Lambda表达式
Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中),或者把代码看成数据:函数式程序员对这一概念非常熟悉。(不多赘述,可以参考js的函数式编程)
语法:
( Type1 param1, Type2 param2,.... TypeN paramn ) ->{
statment1;
statment2;
...
statmentm;
return statment(m+1);
}
当lambda表达式只包含一条语句时,可以省略大括号、return和语句结尾的分号
当lambda表达式的参数个数只有一个,可以省略小括号
例子:
Arrays.asList("a","b","c").forEach( e -> {
String a = e;System.out.println(a);
});
调用List的foreach方法(该方法会遍历list中的每个元素),其中foreach方法接受一个函数(在这个例子中 该函数的表达形式即为 e -> { 函数体 ;} 其中e为该函数的参数将每个遍历到的元素作为参数传递给函数。
注意: 例子中 String a=e 是合法的。因为编译器会推断出参数e的类型 当然如果不习惯的话也可以写成 (String e) -> { String a = e; System.out.println(a); } 这种形式。
在lambda表达式内部使用外部变量类似于匿名内部类,外部变量必须不可变。
例子:
String out = "out";//编译器隐式当成final来处理
Arrays.asList("hello","world").forEach(e -> {
String inner = "inner";
System.out.println( out + inner + e );
});
另外,在lambda中,this不是指向lambda表达式产生的那个SAM对象,而是声明它的外部对象。
2.方法引用
语法
objectName::instanceMethod
ClassName::staticMethod
ClassName::instanceMethod
前两种方式类似,等同于把lambda表达式的参数直接当成instanceMethod|staticMethod的参数来调用。比如System.out::println等同于x->System.out.println(x);Math::max等同于(x, y)->Math.max(x,y)。
最后一种方式,等同于把lambda表达式的第一个参数当成instanceMethod的目标对象,其他剩余参数当成该方法的参数。比如String::toLowerCase等同于x->x.toLowerCase()。
可以这么理解,前两种是将传入对象当参数执行方法,后一种是调用传入对象的方法。
构造器引用语法如下:ClassName::new,把lambda表达式的参数当成ClassName构造器的参数 。例如BigDecimal::new等同于x->new BigDecimal(x)。
3.lambda表达式以及方法引用可以在什么情况下使用?
java8中新增了函数式接口的概念,。函数式接口就是一个具有一个方法的普通接口(java.lang.Runnable,java.util.concurrent.Callable等),可以被隐式转换为lambda表达式。另外java8中增加了一种特殊的注解@FunctionalInterface能够明确声明接口作为函数式接口的意图。
例子:
@FunctionalInterface
interface Test2{
void method();
}
该接口的实现可以使用lambda表达式。
另外 默认方法与静态方法并不影响函数式接口的契约。
浙公网安备 33010602011771号