本文首发:
Java-函数式编程(二)Lambda表达式html
“Lambda 表达式”(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式能够表示闭包(注意和数学传统意义上的不一样)。java
public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { System.out.println("匿名内部类的执行"); } }).start(); }
设计匿名内部类的目的,就是为了方便程序猿将代码做为数据来传递。可是你会发现,这个对象看起来是不少余的,因此咱们不想传入对象,只想传入行为。express
new Thread(()->{ System.out.println("lambda代替内部类"); }).start();
和实现某接口的对象不一样,咱们传入了一段代码块--一个没有名字的函数。->
将参数和表达式主体分开,左边是参数,右边是方法体。编程
Runnable runnable = ()-> System.out.println("hello world");
该Lambda表达式不包含参数(由于是空括号)。闭包
interface Test{ void oneParam(String name); } Test test = s -> System.out.println("oneParam方法传递参数:"+s); test.oneParam("我是传递的值");
控制台输出:
oneParam方法传递参数:我是传递的值
(lambda只能用于函数式接口),若是参数只包含一个参数,能够省略参数的括号。ide
interface Test2{ int add(int a,int b); } Test2 test2 = (x,y) -> x+y; int add = test2.add(10, 10); System.out.println(add);
控制台输出:
20
能够看到,咱们在使用lambda的时候建立了一个函数x+y
,Test2
对象不是表示两个数字的和,而是表示两个数字相加的代码。以上的代码中,参数类型都是由编译器本身推断的,一样,咱们能够明确的声明参数类型:函数式编程
interface Test3{ long add(long a,long b); } Test3 test3 = (long x,long y) -> x+y; long add = test3.add(10, 10);
Error:(25, 64) java: 从lambda 表达式引用的本地变量必须是最终变量或实际上的最终变量函数
String name = "FantJ"; Runnable runnable = ()-> System.out.println("hello " +name); runnable.run(); hello FantJ
上面这段代码,Lambda能够引用非final变量这个属性你能够早已了解,可是你更须要知道,java8只是放松了这一语法的限制,但实际上要求该变量仍是final。spa
能够看到,无论name
在使用lambda
的前仍是后作改动,lambda
都会报错:表达式引用的本地变量必须是最终变量或实际上的最终变量,简单的,咱们能够称他为既成事实上的final变量。因此,lambda也被称为闭包。设计
java中,全部方法都有返回类型,那lambda返回类型是什么呢。
是接口方法的返回类型。这一点前文有体现过。这里再详细解释下。
interface Test{ void oneParam(String name); }
拿这个例子来说,oneParam
方法表示一种行为:接受一个String
,返回void
。只要方法名和行为和Lambda表达式匹配便可完成调用。
注意:若是编译器猜不出参数和返回值的类型,则都将视为Object
处理。