lambda表达式是一个匿名函数,通俗解释是:可以传递的、在以后执行一次或多次的代码块。Java8中引入的特性。
lambda表达式的语法
形式:(参数)-> 表达式
0.若表达式复杂,可以用大括号括起。{语句块}
1.没有参数的情况:仍然需要提供空括号。
()->{for (int i = 100;i >= 0;i--) System.out.println(i);}
2.如果可以推导出参数类型:可以忽略参数类型。
Compertor<String> comp = (first,second) ->first.length()-scond.length();//参数类型必为字符串
3.如果只有一个参数,可以推导出参数类型:可以省略小括号。
4.无需指定lambda表达式的返回类型,自动由上下文推导得出。
函数式接口
对于只有一个抽象方法的接口,需要这种接口的对象时,可以提供一个lambda表达式。只有一个抽象方法的接口被称为函数式接口。
如Array.sort方法需要提供一个数组和比较器(comparator)。比较器是实现了Comparator接口的实例对象。该接口只有一个方法。如普通实现:
class LengthComparater implements Comparator<String>{ public int compare(String first,String second){ return first.length() - second.length(); } }
这样,就可以创建一个LengthComparater类传入Array.sort函数中。
Array.sort(words,new LengthComparator())
而用lambda表达式:
Array.sort(words,(first,second)->first.length()-secong.length())
这样做,对compare方法的调用会执行这个lambda表达式的体,它把lambda看做一个函数。这样做法效率要高;代码可读性也要好一些。
方法引用
使用双冒号(::)分隔方法和对象名来表示一个方法引用,与lambda表达式效果相同。有3种写法:
object::instanceMethod(x,x,x...) 等价于(x,x,x...)->object.instanceMethod(x,x,x...)
Class::staticMethod(x,x,x,....) 等价于(x,x,x...)->object.staticMethod(x,x,x...)
Class::instanceMethod(x,y,z...) 等价于(x)->x.instanceMethod(y,z.....) //第一个参数会成为方法的目标
可以在方法引用中使用this和super参数
构造器引用
与方法引用类似,方法名为new。例如Person::new是Person构造器的一个引用。
变量作用域
lambda表达式可以捕获外围作用域中变量的值,但却有些限制。
规则:lambda表达式中捕获的变量必须实际上是最终变量。
一个例子:
public static void repeat(String text, int count){ for (int i = 1;i <= count; i++){ ActionListener ls = event ->{ System.out.println(i + " " + text); }; new Timer(10000,ls).start(); } }
如上,对于text的打印是合法的,对i的打印却是非法的。text总是指向同一个对象;而i的值却会改变。
规则:lambda表达式的体与嵌套块有相同的作用域。
一个例子:
Path first = Paths.get("usr/bin");
Comparator<String> comb = (first,second) -> first.length()-second.length();
以上是非法的。方法中不能有两个同名的局部变量。所以以上lambda表达式不能使用first变量名作为参数。
处理lambda表达式
简单例子:重复一个动作n次,用到repeat方法。
repeat(10,()->(System.out.println("hello world"));
需要实现一个函数式接口,这里使用Runnable接口,调用action.run()时会执行这个函数主体:
public static void repeat(int n,Runnable action){ for(int i;i<n;i++) action.run(); }
实际上lambda表达式能做的也就是转换成函数式接口。
一些常用的函数式接口:Runnable,Supplier,Consumer,BiConsumer,Function,BiFunction,UnaryOperator,BinaryOperator,Predicate,BiPredicate。