我的位置: 首页 > 学习专区 > JAVA技术 > Java开发教程之Java8 新特性Lambda 表达式介绍

Java开发教程之Java8 新特性Lambda 表达式介绍

2016-10-17 14:45:31
来源:北大青鸟深圳嘉华学校
[导读] Java自问世以来,已经经过了数次升级,这里北大青鸟深圳嘉华学校将介绍Java8的新特性之一——Lambda 表达式,希望这点Java开发教程知识能对Java开发者们有所帮助。首先我们了解一下lambda表达式是什么?说起lambda表达式,第一个需要说明的就是它是Java8的几个重量级新特性之一,它
Java自问世以来,已经经过了数次升级,这里北大青鸟深圳嘉华学校将介绍Java8的新特性之一——Lambda 表达式,希望这点Java开发教程知识能对Java开发者们有所帮助。
首先我们了解一下lambda表达式是什么?
说起lambda表达式,第一个需要说明的就是它是Java8的几个重量级新特性之一,它能使Java程序设计更加简洁。在这篇文章里,我们将通过探讨lambda表达式、依托于函数式接口使用lambda表达式等知识,详细介绍Java8 新特性Lambda 表达式。
关于lambda表达式定义
我们可以将lambda表达式定义为一种 简洁、可传递的匿名函数,首先我们需要明确lambda表达式本质上是一个函数,虽然它不属于某个特定的类,但具备参数列表、函数主体、返回类型,以及能够抛出异常;其次它是匿名的,lambda表达式没有具体的函数名称;lambda表达式可以像参数一样进行传递,从而极大的简化代码的编写。格式定义如下:
格式一: 参数列表 -> 表达式
格式二: 参数列表 -> {表达式集合}
需要注意的是,lambda表达式隐含了return关键字,所以在单个的表达式中,我们无需显式的写return关键字,但是当表达式是一个语句集合的时候,则需要显式添加return,并用花括号{ }将多个表达式包围起来,下面看几个例子:
Java开发教程之Java8 新特性Lambda 表达式介绍1
依托于函数式接口使用lambda表达式
lambda表达式的使用需要借助于函数式接口,也就是说只有函数式接口出现地方,我们才可以将其用lambda表达式进行简化。
自定义函数式接口
函数式接口定义为只具备 一个抽象方法 的接口。java8在接口定义上的改进就是引入了默认方法,使得我们可以在接口中对方法提供默认的实现,但是不管存在多少个默认方法,只要具备一个且只有一个抽象方法,那么它就是函数式接口,如下(引用上面的AppleFilter):
Java开发教程之Java8 新特性Lambda 表达式介绍2
AppleFilter仅包含一个抽象方法accept(Apple apple),依照定义可以将其视为一个函数式接口,在定义时我们为该接口添加了@FunctionalInterface注解,用于标记该接口是函数式接口,不过这个接口是可选的,当添加了该接口之后,编译器就限制了该接口只允许有一个抽象方法,否则报错,所以推荐为函数式接口添加该注解。
jdk自带的函数式接口
jdk为lambda表达式已经内置了丰富的函数式接口,如下表所示(仅列出部分):
Java开发教程之Java8 新特性Lambda 表达式介绍3
下面分别就Predicate<T>、Consumer<T>、Function<T, R>的使用示例说明。
Predicate<T>
Java开发教程之Java8 新特性Lambda 表达式介绍4
Predicate的功能类似于上面的AppleFilter,利用我们在外部设定的条件对于传入的参数进行校验,并返回验证结果boolean,下面利用Predicate对List集合的元素进行过滤:
Java开发教程之Java8 新特性Lambda 表达式介绍5
利用上面的函数式接口过滤字符串集合中的空字符串:
demo.filter(list, (String str) -> null != str && !str.isEmpty());
Consumer<T>
Java开发教程之Java8 新特性Lambda 表达式介绍6
Consumer提供了一个accept抽象函数,该函数接收参数,但不返回值,下面利用Consumer遍历集合:
Java开发教程之Java8 新特性Lambda 表达式介绍7
利用上面的函数式接口,遍历字符串集合,并打印非空字符串:
Java开发教程之Java8 新特性Lambda 表达式介绍8
Function<T, R>
Java开发教程之Java8 新特性Lambda 表达式介绍9
Funcation执行转换操作,输入是类型T的数据,返回R类型的数据,下面利用Function对集合进行转换:
Java开发教程之Java8 新特性Lambda 表达式介绍10
下面利用上面的函数式接口,将一个封装字符串(整型数字的字符串表示)的接口,转换成整型集合:
demo.filter(list, (String str) -> Integer.parseInt(str));
上面这些函数式接口还提供了一些逻辑操作的默认实现,留到后面介绍java8接口的默认方法时再讲吧~
使用过程中需要注意的一些事情
类型推断
在编码过程中,有时候可能会疑惑我们的调用代码会去具体匹配哪个函数式接口,实际上编译器会根据参数、返回类型、异常类型(如果存在)等做正确的判定。
在具体调用时,在一些时候可以省略参数的类型,从而进一步简化代码:
Java开发教程之Java8 新特性Lambda 表达式介绍11
局部变量
上面所有例子我们的lambda表达式都是使用其主体参数,我们也可以在lambda中使用局部变量,如下:
Java开发教程之Java8 新特性Lambda 表达式介绍13
该例子中我们在lambda中使用了局部变量weight,不过在lambda中使用局部变量必须要求该变量 显式声明为final或事实上的final ,这主要是因为局部变量存储在栈上,lambda表达式则在另一个线程中运行,当该线程视图访问该局部变量的时候,该变量存在被更改或回收的可能性,所以用final修饰之后就不会存在线程安全的问题。
评论
热点专题
>>