提升你的代码——Lambda!
歡迎支持筆者新作:《深入理解Kafka:核心設計與實踐原理》和《RabbitMQ實戰指南》,同時歡迎關注筆者的微信公眾號:朱小廝的博客。
歡迎跳轉到本文的原文鏈接:https://honeypps.com/java/java-lambda-quick-start/
前言
上個月(2018年2月)看過一份調研報告,對于Java版本而言,生產環境中用的最多的是JDk6和JDK7,雖然JDK8在自2014年3月發布至今使用占比仍然很小,想想月底JDK10都要出來了呀。JDk8引入了很多新的特性,比如接口默認值、方法引用、Lambda表達式、函數式接口、Optional、Stream等等,這些在其他語言中并不少見的玩意兒,現今在Java中卻還很少使用,很多時候我們會對新事物(其實已經不新鮮)抱著一種比較保守的態度:反正我司還沒用到,學了也無用武之地;讓別人先去踩踩坑、我來大樹底下好乘涼;又學新東西?我JDK7都沒學完,又TMD要學JDk8、9、10?累覺不愛啊,筆者也一直保持著這種心態,但是一顆好奇的心促使我小小的往前邁了那么一小步……
好奇之心
平常擼代碼的時候經常也會涉及一些多線程的東西,比如使用Future和Callable來搞一些事情,代碼舉例如下:
對于這段代碼在搞什么事情這里就不多說了,值得注意的是IDEA里給“new Callable()”這段代碼“特殊”照顧了一下(注意IDE的language level要設置成JDK8及以上的),想必是要告訴我一些隱晦的事情,本著一顆少男的好奇心我默默的瀏覽了下提示信息,詳細如下圖:
內心的躁動讓我小小點擊了“Replace with lambda”一下?代碼迅速地做了切換:
What an AMAZING thing! 代碼立馬簡潔了許多,整個Callable接口的實現只保留了關鍵的“()->“lambda demo””。這個不止在使用Callable的時候發生,常用的Runnable、Comparator中都會如此,JDK8到底對它們做了什么改變?! 我們不妨舉一個DEMO從最初的夙愿來一步步撥開這一層層面紗~~
循序漸進
DEMO需求:對一個數字型的字符串列表做排序,這個列表很簡單,具體如下:
List<String> list = Arrays.asList("2", "3", "1", "4");這個需求很簡單,實現起來不需要1分鐘:
Comparator<String> comparator = new Comparator<String>() {@Overridepublic int compare(String o1, String o2) {return Integer.valueOf(o1) - Integer.valueOf(o2);} }; list.sort(comparator);注意本文中所使用的JDK版本為8,所以你看到List的sort()方法的時候不要感到太意外,這是List接口中用默認方法實現的一個新方法:default void sort(Comparator<? super E> c)。對于上面的實現我們還可以很傲嬌的改用一下匿名類的方式:
list.sort(new Comparator<String>() {@Overridepublic int compare(String o1, String o2) {return Integer.valueOf(o1) - Integer.valueOf(o2);} });如果是JDK7,那么用一下Collections.sort()方法,然后差不多實現到這里就結束了,然后JDK8才剛剛開始,我們可以通過進一步的把這個方法改為Lambda表達式的形式實現:
list.sort((String o1, String o2) -> Integer.valueOf(o1) - Integer.valueOf(o2));好了,一下子就變成一行代碼了,只不過看上去比原先的有那么一丟丟的晦澀。正如上面所說的Callable也好、Runnable也好,和Comparator這種都屬于函數式接口,如果你打開源碼可以發現這三個接口都有一個相同的注解——@FuncationalInterface。如果你所使用的方法中包含有函數式接口,那么你就可以使用Lambda表達式。函數式接口是一種有且只有一個抽象方法的接口,如果標注為@FunctionalInterface的接口沒有抽象方法(空接口也就是標記接口,或者接口中的方法都是默認方法)或者擁有超過一個抽象方法的話都會報錯。
類似于( //會報錯:No target method found.):
或者這樣(//會報錯:Multiple non-overriding abstract methods found in interface FunctionError):
@FunctionalInterface public interface FunctionError{public String method1(String o1, String o2);public String method2(Integer o1, Boolean o2); }都是無效的,可以將上面的其中一個方法改為默認方法:
@FunctionalInterface public interface FunctionCorrect{public String method1(String o1, String o2);default public String method2(Integer o1, Boolean o2){return "why not rabbitmq or kafka?";}; }這樣就沒有問題。
這里我們先來小結一下——Lambda表達式一個有三個部分:
可以看到Lambda的基本語法為:
或者:
(參數列表)-> {語句}Java還可以推斷出Lambda表達式中的參數類型,上面的代碼還可以進一步優化去掉參數類型的聲明:
list.sort((o1, o2) -> Integer.valueOf(o1) - Integer.valueOf(o2));對于上面的代碼中Integer本身就具有“可比性”(實現了Comparable)接口,上面的代碼可以改寫成:
list.sort((o1, o2) -> Integer.valueOf(o1).compareTo(Integer.valueOf(o2)));不過這樣的代碼易讀性好像也不是很高,我們這里做進一步的改進,這里引入了一個新的概念——方法引用。方法引用讓你可以重復使用現有的方法定義,并像Lambda一樣傳遞他們,在某些情況下,他們更加的易讀。上面的代碼可以進一步的改寫成:
list.sort(Comparator.comparing(Integer::valueOf));這樣的代碼可以看出我們對于String列表的排序規則時其int類型的值,而不用再關注有點晦澀的Lambda語句。如果有一天寶寶不開心了,不按照其轉換的int值排序,而是按照其hashCode排序怎么辦呢,很簡單:
list.sort(Comparator.comparing(String::hashCode));如果寶寶又不開了,原本是升序排序的,現在要按降序排序的怎么辦呢?改寫Lambda表達式,比如這樣:
list.sort((o1, o2) -> Integer.valueOf(o2).compareTo(Integer.valueOf(o1)));不如這樣:
list.sort(Comparator.comparing(Integer::valueOf).reversed()); //or list.sort(Comparator.comparing(String::hashCode).reversed());是不是通俗易懂又方便?方法引用的基本思想是:如果一個Lambda代表的只是直接調用這個方法,那最好還是用名稱來調用它,而不是去描述如何調用它。事實上,方法引用就是讓你根據已有的方法實現來創建Lambda表達式,只不過顯示地指明方法的名稱,代碼可讀性會高一點。當你需要使用方法引用時,將目標引用放在分隔符::前,而方法的名稱放在后面。例如:
(String s) -> System.out.println(s) 可以等效為 System.out:println要不你try一下下面的代碼看看效果是不是一樣的?
public class FunctionDemo {@FunctionalInterfacepublic interface FunctionQuote{public void print(String arg);}public static void process(FunctionQuote functionQuote){String str = "http://blog.csdn.net/u013256816";functionQuote.print(str);}public static void main(String[] args) {process((String s) -> System.out.println(s));process(System.out::println);} }歡迎跳轉到本文的原文鏈接:https://honeypps.com/java/java-lambda-quick-start/
歡迎支持筆者新作:《深入理解Kafka:核心設計與實踐原理》和《RabbitMQ實戰指南》,同時歡迎關注筆者的微信公眾號:朱小廝的博客。
總結
以上是生活随笔為你收集整理的提升你的代码——Lambda!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Kafka解析之topic创建(2)
- 下一篇: 集群管理工具KafkaAdminClie