java8保姆級lambda表達式教程
1.替代匿名內部類
毫無疑問,lambda表達式用得最多的場合就是替代匿名內部類,而實現Runnable接口是匿名內部類的經典例子。lambda表達式的功能相當強大,用()->就可以代替整個匿名內部類!請看代碼:
如果使用匿名內部類:
@Test public void oldRunable() { new Thread(new Runnable() { @Override public void run() { System.out.println("The old runable now is using!"); } }).start(); }
而如果使用lambda表達式:
@Test public void runable() { new Thread(() -> System.out.println("It's a lambda function!")).start(); }
最後的輸出:
The old runable now is using!
It's a lambda function!
是不是強大到可怕?是不是簡單到可怕?是不是清晰明瞭重點突出到可怕?這就是lambda表達式的可怕之處,用極少的代碼完成瞭之前一個類做的事情!
2.使用lambda表達式對集合進行迭代
Java的集合類是日常開發中經常用到的,甚至說沒有哪個java代碼中沒有使用到集合類。。。而對集合類最常見的操作就是進行迭代遍歷瞭。請看對比:
@Test public void iterTest() { List<String> languages = Arrays.asList("java","scala","python"); //before java8 for(String each:languages) { System.out.println(each); } //after java8 languages.forEach(x -> System.out.println(x)); languages.forEach(System.out::println); }
如果熟悉scala的同學,肯定對forEach不陌生。它可以迭代集合中所有的對象,並且將lambda表達式帶入其中。
languages.forEach(System.out::println);
這一行看起來有點像c++裡面作用域解析的寫法,在這裡也是可以的。
3.用lambda表達式實現map
一提到函數式編程,一提到lambda表達式,怎麼能不提map。。。沒錯,java8肯定也是支持的。請看示例代碼:
@Test public void mapTest() { List<Double> cost = Arrays.asList(10.0, 20.0,30.0); cost.stream().map(x -> x + x*0.05).forEach(x -> System.out.println(x)); }
最後的輸出結果:
10.5
21.0
31.5
map函數可以說是函數式編程裡最重要的一個方法瞭。map的作用是將一個對象變換為另外一個。在我們的例子中,就是通過map方法將cost增加瞭0,05倍的大小然後輸出。
4.用lambda表達式實現map與reduce
既然提到瞭map,又怎能不提到reduce。reduce與map一樣,也是函數式編程裡最重要的幾個方法之一。。。map的作用是將一個對象變為另外一個,而reduce實現的則是將所有值合並為一個,請看:
@Test public void mapReduceTest() { List<Double> cost = Arrays.asList(10.0, 20.0,30.0); double allCost = cost.stream().map(x -> x+x*0.05).reduce((sum,x) -> sum + x).get(); System.out.println(allCost); }
最終的結果為:
63.0
如果我們用for循環來做這件事情:
@Test public void sumTest() { List<Double> cost = Arrays.asList(10.0, 20.0,30.0); double sum = 0; for(double each:cost) { each += each * 0.05; sum += each; } System.out.println(sum); }
相信用map+reduce+lambda表達式的寫法高出不止一個level。
5.filter操作
filter也是我們經常使用的一個操作。在操作集合的時候,經常需要從原始的集合中過濾掉一部分元素。
@Test public void filterTest() { List<Double> cost = Arrays.asList(10.0, 20.0,30.0,40.0); List<Double> filteredCost = cost.stream().filter(x -> x > 25.0).collect(Collectors.toList()); filteredCost.forEach(x -> System.out.println(x)); }
最後的結果:
30.0
40.0
將java寫出瞭python或者scala的感覺有沒有!是不是帥到爆!
6.與函數式接口Predicate配合
除瞭在語言層面支持函數式編程風格,Java 8也添加瞭一個包,叫做 java.util.function。它包含瞭很多類,用來支持Java的函數式編程。其中一個便是Predicate,使用 java.util.function.Predicate 函數式接口以及lambda表達式,可以向API方法添加邏輯,用更少的代碼支持更多的動態行為。Predicate接口非常適用於做過濾。
public static void filterTest(List<String> languages, Predicate<String> condition) { languages.stream().filter(x -> condition.test(x)).forEach(x -> System.out.println(x + " ")); } public static void main(String[] args) { List<String> languages = Arrays.asList("Java","Python","scala","Shell","R"); System.out.println("Language starts with J: "); filterTest(languages,x -> x.startsWith("J")); System.out.println("\nLanguage ends with a: "); filterTest(languages,x -> x.endsWith("a")); System.out.println("\nAll languages: "); filterTest(languages,x -> true); System.out.println("\nNo languages: "); filterTest(languages,x -> false); System.out.println("\nLanguage length bigger three: "); filterTest(languages,x -> x.length() > 4); }
最後的輸出結果:
Language starts with J:
JavaLanguage ends with a:
Java
scalaAll languages:
Java
Python
scala
Shell
RNo languages:
Language length bigger three:
Python
scala
Shell
可以看到,Stream API的過濾方法也接受一個Predicate,這意味著可以將我們定制的 filter() 方法替換成寫在裡面的內聯代碼,這也是lambda表達式的魔力!
到此這篇關於java8手把手教你學會寫lambda表達式的文章就介紹到這瞭,更多相關java8教你學會lambda表達式內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Java與Scala創建List與Map的實現方式
- 關於JAVA8的 Stream學習
- Java中list.foreach不能使用字符串拼接的問題
- java中lambda(函數式編程)一行解決foreach循環問題
- Java中Lambda表達式用法介紹