您的位置:首页 > 编程语言 > Java开发

Java8新特性——Lambda表达式(一)语法基础

2016-08-25 18:12 211 查看
首先我们看一下什么是lambda表达式。以下是维基百科上对于”Lambda expression”的解释:

 a function (or a subroutine) defined, and possibly called, without being bound to an identifier。

简单点说就是:一个不用被绑定到一个标识符上,并且可能被调用的函数。这个解释还不够通俗,lambda表达式可以这样定义(不精确,自己的理解):一段带有输入参数的可执行语句块。

函数式接口

函数式接口(functional interface 也叫功能性接口,其实是同一个东西)。简单来说,函数式接口是只包含一个方法的接口。比如Java标准库中的java.lang.Runnable和java.util.Comparator都是典型的函数式接口。java
8提供@FunctionalInterface作为注解,这个注解是非必须的,只要接口符合函数式接口的标准(即只包含一个方法的接口),虚拟机会自动判断,但 最好在接口上使用注解@FunctionalInterface进行声明,以免团队的其他人员错误地往接口中添加新的方法。Java中的lambda无法单独出现,它需要一个函数式接口来盛放,lambda表达式方法体其实就是函数接口的实现。

Lambda语法详解

包含三个部分:
1、一个括号内用逗号分隔的形式参数,参数是函数式接口里面方法的参数
2、一个箭头符号:->
3、方法体,可以是表达式和代码块,方法体函数式接口里面方法的实现,如果是代码块,则必须用{}来包裹起来,且需要一个return 返回值,但有个例外,若函数式接口里面方法返回值是void,则无需{}

我们在此抽象一下lambda表达式的一般语法:

1
(Type1
param1, Type2 param2, ..., TypeN paramN) -> {
2
  
statment1;
3
  
statment2;
4
  
//.............
5
  
return
 
statmentM;
6
}
从lambda表达式的一般语法可以看出来,还是挺符合上面给出的非精确版本的定义–“一段带有输入参数的可执行语句块”。上面的lambda表达式语法可以认为是最全的版本,写起来还是稍稍有些繁琐。别着急,下面陆续介绍一下lambda表达式的各种简化版:

1. 参数类型省略–绝大多数情况,编译器都可以从上下文环境中推断出lambda表达式的参数类型。这样lambda表达式就变成了:

1
(param1,param2,
..., paramN) -> {
2
  
statment1;
3
  
statment2;
4
  
//.............
5
  
return
 
statmentM;
6
}
所以我们最开始的例子就变成了(省略了List的创建):

1
List<String>
lowercaseNames = names.stream().map((name) -> {
return
name.toLowerCase();}).collect(Collectors.toList());
2. 当lambda表达式的参数个数只有一个,可以省略小括号。lambda表达式简写为:

1
param1
-> {
2
  
statment1;
3
  
statment2;
4
  
//.............
5
  
return
 
statmentM;
6
}
所以最开始的例子再次简化为:

1
List<String>
lowercaseNames = names.stream().map(name -> {
return
name.toLowerCase();}).collect(Collectors.toList());
3. 当lambda表达式只包含一条语句时,可以省略大括号、return和语句结尾的分号。lambda表达式简化为:

1
param1
-> statment
所以最开始的例子再次简化为:

查看源代码

打印帮助

1
List<String>
lowercaseNames = names.stream().map(name -> name.toLowerCase()).collect(Collectors.toList());

方法引用

其实是lambda表达式的一个简化写法,所引用的方法其实是lambda表达式的方法体实现,语法也很简单,左边是容器(可以是类名,实例名),中间是"::",右边是相应的方法名。
一般方法的引用格式是:
1、如果是静态方法,则是ClassName::methodName。如 Object::equals
2、如果是实例方法,则是Instance::methodName。如Object obj=new Object();obj::equals;

构造器引用

构造器引用语法如下:ClassName::new,把lambda表达式的参数当成ClassName构造器的参数 。例如BigDecimal::new等同于x->new BigDecimal(x)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: