Java lambda表達式
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看做一個函數。這樣做法效率要高;代碼可讀性也要好一些。
方法引用
使用雙冒號(::)分隔方法和對象名來表示一個方法引用
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。
Java lambda表達式