Java Lambda表达式(一)

Lambda表达式简介

Java 8新引入Lambda表达式。

注意Lambda表达式只能用来替代函数式接口(函数式接口是只包含有一个抽象方法的接口,哪怕有很多个默认方法,只有只有一个抽象方法,就是函数式接口)!甚至不能把Lamda表达式赋值给Object!即仍然保持使用接口的习惯,只是将接口的实现类编写简化成Lambda表达式。具体来说,Lambda表达式其实是函数式接口中的函数的实现。

推荐给所有的函数式接口上加上@FunctionalInterface,表示这是一个函数式接口。

举例说明:

Comparator是一个接口,主要用于Arrays类的静态排序方法sort里指定排序的规则。

比如如果希望对字符串进行排序,排序规则为字符串的长度。如果不用Lambda表达式的话,我们一般会用一个匿名内部类来实现:

//创建Compartor接口的匿名实现
Comparator<String> comparator = new Comparator<String>() {
      @Override
      public int compare(String o1, String o2) {
           return Integer.compare(o1.length(),o2.length());
      }
};

//调用comparator对象进行排序
String[] words = new String[]{"l1111","l222"};
Arrays.sort(words,comp);

Lambda表达式的作用即在于替代上面的匿名实现部分,即:

//使用Lambda表达式写函数式接口实现
Comparator<String> comp = (first,second)->Integer.compare(first.length(),second.length());

固使用Lambda表达式有两个条件:

  1. 定义好的函数式接口
  2. 定义好的调用该函数式接口的方法

当然,由于Lambda表达式一般是“一次性用品”,所以一般我们会这样写:

Arrays.sort(words,(first,second)->Integer.compare(first.length(),second.length()));

由于隐去了接口对象的声明,同时隐去了变量类型的声明,所以有一些代码显得不明所以。

最后提示:

  1. 不需要声明参数的类型
  2. 不需要声明返回值的类型,在简单的情况下甚至不需要使用return。在比较复杂的情况下,可以像写方法一样写Lambda表达式,使用(x1,x2)->{    /*注意这里是花括号 */     };的形式写lambda表达式
  3. Lambda表达式可以没有限制地使用参数、实例变量和静态变量,但是如果想使用局部变量则必须显式地使用final修饰

Lambda表达式和闭包

闭包就是一个函数的实例,且它可以无限制地访问那个函数的非本地变量。例如,闭包可以作为参数传递给另一个函数。它也可以访问和修改其作用域之外的变量。

现在, Java 8的Lambda和匿名类可以做类似于闭包的事情:它们可以作为参数传递给方法,并且可以访问其作用域之外的变量。但有一个限制:它们不能修改定义Lambda的方法的局部变量的内容。这些变量必须是隐式最终的。可以认为Lambda是对值封闭,而不是对变量封闭。

这种限制存在的原因在于局部变量保存在栈上,并且隐式表示它们仅限于其所在线程。如果允许捕获可改变的局部变量,就会引发造成线程不安全的新的可能性,而这是我们不想看到的(实例变量可以,因为它们保存在堆中,而堆是在线程之间共享的) 。
 

转载于:https://my.oschina.net/pierrecai/blog/845748

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值