Java JVM(八):Lambda 簡介

一. 爲什麼需要lambda
二. lambda 語法
三. lambda 配合 Function 等接口的使用
四. lambda 配合 集合的使用

一. 爲什麼需要 lambda
        Java是一種面向對象的編程方式。而 lambda 屬於一種 函數式編程。Java 爲什麼要引入?
        1. 結合函數式接口,可以消除很多重複性代碼。例如:
public class Test {
	public static void main(String[] args) throws InterruptedException {
		String name = "";
		String name1 = "12345";
		System.out.println(validInput(name, inputStr -> inputStr.isEmpty() ? "名字不能爲空":inputStr));
		System.out.println(validInput(name1, inputStr -> inputStr.length() > 3 ? "名字過長":inputStr));
	}
	
	public static String validInput(String name,Function<String,String> function) {
		return function.apply(name);
	}
}
        上述代碼使用了lambda 表達式,如果不用這種方式,需要寫比較多的 if 語句。
        再比如,lambda 表達式可以代替匿名內部類。
        
        2. 結合 集合的流式操作可以充分利用 CPU,利用現代多核的特性,提升效率。例如:
    // 統計年齡在25-35歲的男女人數、比例  
    public void boysAndGirls(List<Person> persons) {  
        Map<Integer, Integer> result = persons.parallelStream().filter(p -> p.getAge()>=25 && p.getAge()<=35).  
            collect(  
                Collectors.groupingBy(p->p.getSex(), Collectors.summingInt(p->1))  
        );  
        System.out.print("boysAndGirls result is " + result);  
        System.out.println(", ratio (male : female) is " + (float)result.get(Person.MALE)/result.get(Person.FEMALE));  
    }  
        如上的 parallelStream 方法,即獲取並行流,以達到充分利用多核的特性。

二. lambda 語法
        由三部分組成: 參數列表,箭頭( ->),表達式或者語句塊
簡單例子:
// 1. 不需要參數,返回值爲 5  
() -> 5  
// 2. 接收一個參數(數字類型),返回其2倍的值  
x -> 2 * x  
// 3. 接受2個參數(數字),並返回他們的差值  
(x, y) -> x – y  
// 4. 接收2個int型整數,返回他們的和  
(int x, int y) -> x + y  
// 5. 接受一個 string 對象,並在控制檯打印,不返回任何值(看起來像是返回void)  
(String s) -> System.out.print(s)  
解釋:
  1. 參數類型省略–絕大多數情況,編譯器都可以從上下文環境中推斷出lambda表達式的參數類型。例如上面的第二條 x 和第三條 (x,y) 都沒聲明類型。
  2. 當lambda表達式的參數個數只有一個,可以省略小括號。 如上面 第二條的 x
  3. 當lambda表達式只包含一條語句時,可以省略大括號、return和語句結尾的分號。如上面的返回都沒有 return 這東西。
  4. lambda 表達式 可以訪問外部變量(外部變量不可變)。
三. lambda 配合 Function 等接口的使用
如下,配合 Function,Consumer,Predicate 接口的使用,減少了代碼的冗餘:
public class Test {
	public static void main(String[] args) throws InterruptedException {
		String name = "";
		String name1 = "12345";
		System.out.println(validInput(name, inputStr -> inputStr.isEmpty() ? "名字不能爲空":inputStr));
		System.out.println(validInput(name1, inputStr -> inputStr.length() > 3 ? "名字過長":inputStr));
	}
	
	public static String validInput(String name,Function<String,String> function) {
		return function.apply(name);
	}
}
public class Test {
	public static void main(String[] args) throws InterruptedException {
		String name = "";
		String name1 = "12345";
		
		validInput(name, inputStr ->  
				System.out.println(inputStr.isEmpty() ? "名字不能爲空":"名字正常"));
		validInput(name1, inputStr ->
				System.out.println(inputStr.isEmpty() ? "名字不能爲空":"名字正常"));
		
	}
	public static void validInput(String name,Consumer<String> function) {
		function.accept(name);
	}
}
public class Test {
	public static void main(String[] args) throws InterruptedException {
		String name = "";
		String name1 = "12";
		String name2 = "12345";
		
		System.out.println(validInput(name,inputStr ->  !inputStr.isEmpty() &&  inputStr.length() <= 3 ));
		System.out.println(validInput(name1,inputStr ->  !inputStr.isEmpty() &&  inputStr.length() <= 3 ));
		System.out.println(validInput(name2,inputStr ->  !inputStr.isEmpty() &&  inputStr.length() <= 3 ));
		
	}
	public static boolean validInput(String name,Predicate<String> function) {
		return function.test(name);
	}
}

四.lambda 配合 集合的使用
//給出一個String類型的數組,求其中所有不重複素數的和  
public void distinctPrimarySum(String... numbers) {  
    List<String> l = Arrays.asList(numbers);  
    int sum = l.stream()  
        .map(e -> new Integer(e))  
        .filter(e -> Primes.isPrime(e))  
        .distinct()  
        .reduce(0, (x,y) -> x+y); // equivalent to .sum()  
    System.out.println("distinctPrimarySum result is: " + sum);  
        Ps: lambda 配合 集合的使用應該是 JDK8 最重要的特性,既能簡便了代碼,也充分利用了現代多核的特性,各方面都提升了效率。

總結:
  1. 引入lambda:代碼更簡單,配合其他使用效率更高。
  2. lambda語法:基本組成由 參數列表,箭頭,表達式組成。如果參數列表和表達式簡單,還可以把括號什麼的進一步省略。
  3. Lambda的使用:一般配合 Function,Consumer,Predicate或者自定義的函數式接口使用,使得代碼更加方便;同時也配合集合使用,提升效率,提高閱讀性。

參考:
1. Java8  爲什麼需要Lambda 表達式:http://developer.51cto.com/art/201304/387681.htm
2. Java8 初體驗(一) lambda 表達式語法:http://ifeve.com/lambda/

發佈了97 篇原創文章 · 獲贊 19 · 訪問量 24萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章