JDK8 ——lambda表达式

1、为什么要使用lambda表达式

lambda表达式是一段可以传递的代码,因此它可以被执行一次或多次。

在jdk8之前,向其他代码传递一段代码不是很容易,我们不能将代码块到处传递。我们需要构建一个属于某个类的对象,由它的某个方法来包含所需的代码。在其他一些语言中可以直接使用代码块。在过去的很长一段时间里,java设计者们都拒绝加入这一特性。java的优势本就在于他的简单和一致性。如果加入可以略微简化的代码,其将不易于维护。当然,还有一方面是,其他语言有大量的简单、一致、强大的API,java中的API却没有能达到这种效果。

基于以上,最近一段时间,大家不再讨论是否需要使用了,而是在讨论该怎么实现。并且很可喜的是,在jdk8中已经做了实现。


2、lambda表达式的语法

其格式为:参数、箭头->,以及一个表达式。如果相关代码无法用一个表达式表示,可以用编写方法的方式编写:既可以使用{}包裹代码并明确使用return语句。

如一个做比较的表达式可以这么写:

Comparator<String> comp = (String first, String second) -> Integer.compare(first.length(), second.length());
如果lambda表达式没有参数,可以提供一对空的小括号,如同不含参数的方法那样。

如果一个表达式的参数类型是可以被推导是,可以省略它们的类型。比如上面的String fisrt及后面的second的String参数都是可以不要的。

永远不需要为lambda表达式执行返回类型,它总是会从上下文中被推导出来。


3、函数式接口

对于只包含一个抽象方法的接口,可以通过lamba表达式来创建该接口的对象。


4、方法引用

当想要传递给其他代码的操作已经有了实现的方法,就可以使用方法引用。方法引用有三种主要的使用情况:

a、对象::实例方法

b、类::静态方法

c、类::实例方法


5、构造器引用

构造器引用同方法引用类似,不同的是在构造器引用中方法名是new。

如Button::new表示Button类的构造器引用。对于拥有多个构造器的类,选择使用哪个构造器取决于上下文。


6、变量作用域

通常,我们希望可以在lambda表达式的闭合方法或类中访问其他的变量。

一个lambda表达式包括三个部分:

a、一段代码;b、参数;c、自由变量的值,自由指的是那些不是参数并且没有在代码中定义的变量。

lambda表达式可以捕获闭合作用域中的变量值,由此需要遵守一个约束,在lambda表达式中被引用的变量的值不可以被更改。更改lambda表达式中的变量不是线程安全的。

lambda表达式的方法体与嵌套代码块有着相同的作用域。也适用于同样的命名冲突和屏蔽规则。即不允许声明一个与局部变量同名的参数或者局部变量。不能有两个同名的局部变量。在lambda中使用this关键字时,会引用创建该lambda表达式的方法的this关键字。


7、默认方法

许多开发语言都将函数表达式集成到了其集合库中。

如果一个接口中定义了一个默认方法,而另外一个父类或接口中又定义一个同名的方法,该选择哪个?java中的规则如下:

a、选择父类中的方法。如果一个父类提供了具体的实现方法,那么接口中具有相同名称和参数的默认方法会被忽略。

b、接口冲突。如果一个父接口提供了一个默认方法,而另一个接口也提供了一个具有相同名称和参数类型的方法(不管该方法是否是默认方法),那么你必须通过覆盖该方法类解决冲突。

如此设计是为了实现“类优先”的规则,并且可以和之前的设计相兼容,不会因为在新接口中添加了一个默认方法,就导致跟之前版本不兼容了。


8、接口中的静态方法

在jdk8中,可以为接口添加静态方法。从技术角度来说,这是完全合法的。只是它看起来违反了接口作为一个抽象定义的理念。

在jdk8中,很多接口已经添加了静态方法。c

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值