Java 8 開發頂尖技巧
我使用Java 8編碼已經有些年頭,既用於新的應用程序,也用來遷移現有的應用,感覺是時候寫一些我發現的非常有用的「最佳實踐」。我個人並不喜歡「最佳實踐」這個說法,因為它意味著「一刀切」的解決方案,而編碼不可能是這樣的工作方式——我們需要親自去發現什麼樣的解決方案才是有效的。但是我發現了一些Java 8程式碼中可以幫助我們的一些選擇,讓我們一起來看看吧。
1.Optional
Optional
是一個嚴重被低估的功能,有潛力刪除許多困擾我們的NullPointerExceptions
。這在程式碼邊界中(要么是正在使用的API,要么是正在暴露的API)特別有用,因為它允許你和你的呼叫程式碼來推理所期待的東西。
然而,不加思考和設計就應用Optional可能會導致影響大量的類,並可能導致可讀性較差。以下是一些關於如何有效使用Optional的技巧。
Optional應該只用於傳回類型
…不是參數,也不是欄位。幸運的是,IntelliJ IDEA的讓你打開檢查來查看是否遵循這些建議。
Optional值應在遇到它們的地方中處理。 IntelliJ IDEA的建議會防止代碼Optional洩漏,所以請記得在你發現Optional的地方處理它,並迅速採取行動。
不應該簡單地呼叫get()
Optional的函數是表達這個值可能是空的,並讓你處理這種情況。因此,在對它做任何事情之前一定要檢查是否有一個值。只是簡單得呼叫get()
而不先檢查isPresent()在某些時候可能會導致空指標。幸運的是,IntelliJ IDEA也有檢查可以提醒你這一點。
可能有更優雅的方式
#結合了get()的isPresent()
當然會很讚…
…但也有更優雅的解決方案。你可以使用orElse在萬一是空值的情況下給一個替代方案。
…或者你可以使用orElseGet
來說明在值為空的情況下呼叫哪個方法。這似乎與上面的例子相同,但supplier方法將只在需要的時候調用,因此,如果這是一種昂貴的方法,那麼使用lambda會有更佳效能。
2.使用Lambda表達式
Lambda表達式是Java 8的主要特性之一。即使你還沒有使用Java 8,你現在可能已經對它們有了基本的了解。它們是用Java編程的一種新的方式,並且什麼是“最佳實踐”還不明顯。以下是我喜歡遵循的一些指引。
保持簡短
函數式程式設計與較長的lambda表達式相處會更愉快,但那些淫浸於Java多年的人會發現保持lambda表達式為區區幾行程式碼更容易。你甚至可能更願意將其限製到一行程式碼,並且你可以輕鬆重構較長的表達式為一個方法。
這些甚至可能會成為方法參考。方法引用一開始會覺得有點陌生,但實際上堅持方法引用是有價值的,因為它們在某些情況下有助於可讀性,後面我會討論到這一點。
明確
類型資訊缺少lambda表達式,所以你可能會覺得包含型別資訊用於參數會很有用。
如你所見,這回變得相當笨拙。所以我比較喜歡給參數取一個有用的名字。當然,不管你有沒有這麼做,IntelliJ IDEA可以讓你看到參數得類型資訊。
甚至是lambda所代表的函數式介面:
3.針對Lambda表達式設計
我認為lambda表達式有點像泛型——和泛型一起,我們經常使用它們(例如,添加類型資訊到List<>),但最好我們可以設計一種方法或具有泛型類型(例如Person<T>
)的類別。同樣的,當使用類似Streams API的東西時,我們會傳遞lambda表達式,但更好的是創造一個需要lambda參數的方法。
但是,如果你發現自己處於這類情況下,下面有一些超棒的技巧。
IntelliJ IDEA可以幫你引進函數式參數
這讓你可以在有人將要傳遞一個lambda而非Object的地方建立一個參數。此功能的好處是,它表明,現有函數式介面匹配規格說明。
這會導致…
使用現有的函式介面
隨著開發人員越來越熟悉Java 8程式碼,我們就能知道當使用如Supplier
和 Consumer的介面時,會發生什麼,以及創建一個本地的ErrorMessageCreator(舉個例子)可能會造成混亂,而且浪費。看看這個函數包了解哪些已經是可用的。
新增@FunctionalInterface到函數式接口
如果你確實需要建立自己的函數式接口,那麼就這樣用此註解標記。這似乎沒有太大的作用,但IntelliJ IDEA會告訴你,在你的介面不能匹配用於函數式介面的異常的時候。當你沒有指定要覆寫的方法時,它會標誌:
當你指定了太多方法的時候,它會標誌:
並且如果你應用它到一個類別而不是介面時,它會警告你:
排隊點操作符
我個人更喜歡排隊我的串流操作。當然,你沒有必要這樣,當我發現這樣做對我有幫助:- 一目了然地看到我有哪些操作
- 調試更容易(雖然IntelliJ IDEA確實提供了對一行中的任意多個lambda表達式設定斷點的能力,但是拆分到不同的行會變得更簡單)
- 當我測試東西的時候註解操作
- 輕鬆插入
peek()
用於調試或測試
此外,在我看來,它更整齊。如果我們按照這個模式,在減少程式碼行數方面我們並沒有增加很多。
你可能需要調整格式設定以排列點運算元。
使用方法來引用
是的,確實需要一段時間來適應這個奇怪的語法。但是,如果使用得當,它確實可以增加可讀性。請看:
與(相對)新的Objects
類別上的輔助方法比較:
後者的程式碼對於哪些值是要保存的更加明確。當lambda可以被折疊到方法參考的時候,IntelliJ IDEA通常會讓你知道。
當遍歷一個集合時,在可行的情況下使用Streams API
…或新的集合方法,如forEach
。 IntelliJ IDEA給你建議是:
一般使用Streams API比迴圈和if語句的組合更明確。例如:
IntelliJ IDEA建議這可重構為:
我所做的效能測試表明這種重構令人驚訝——並不總是可預測性能是保持不變,改善還是變得更糟。與往常一樣,如果效能在應用程式中是關鍵,那麼在交付一種風格到另一種風格之前衡量它。
遍歷陣列時使用循環
但是,使用Java 8並不一定意味著你必須到處使用流和新的集合方法。 IntelliJ IDEA會建議轉換成流,但是,這並不意味著你必須回答「yes」(記得檢查是可以抑製或關閉的)。
特別是,遍歷原始類型的小型陣列幾乎肯定會用,以獲得更好的效能循環,很可能(至少對於Java開發人員是新的串流)更具可讀性。
與任何技巧一樣,規則並不是一成不變的,但你應該決定是盡可能地使用Streams API,還是依然對一些操作使用循環。總之,要一致。
最後
以上就是Java 8 開發頂級技巧 的內容,更多相關內容請關注PHP中文網(www.php.cn)!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Java8計算一年前或一年後的日期利用minus()方法計算一年前的日期packagecom.shxt.demo02;importjava.time.LocalDate;importjava.time.temporal.ChronoUnit;publicclassDemo09{publicstaticvoidmain(String[]args ){LocalDatetoday=LocalDate.now();LocalDatepreviousYear=today.minus(1,ChronoUni

Java8如何計算一週後的日期這個例子會計算一週後的日期。 LocalDate日期不包含時間訊息,它的plus()方法用來增加天、週、月,ChronoUnit類別宣告了這些時間單位。由於LocalDate也是不變型,回傳後一定要用變數賦值。 packagecom.shxt.demo02;importjava.time.LocalDate;importjava.time.temporal.ChronoUnit;publicclassDemo08{publicstaticvoidmain(String[

Java8的Clock時鐘類別Java8增加了一個Clock時鐘類別用於取得當時的時間戳,或目前時區下的日期時間資訊。以前用到System.currentTimeInMillis()和TimeZone.getDefault()的地方都可用Clock替換。 packagecom.shxt.demo02;importjava.time.Clock;publicclassDemo10{publicstaticvoidmain(String[]args){//Returnsthecurrenttimebase

Java8日期比較方法在Java8中,可以使用新的isBefore(),isAfter(),isEqual()和compareTo()來比較LocalDate,LocalTime和LocalDateTime。以下範例以比較兩個java.time.LocalDate@TestvoidtestDateCompare4()throwsParseException{DateTimeFormattersdf=DateTimeFormatter.ofPattern("yyyy-MM-dd"

Java8中處理時區Java8不只分離了日期和時間,也把時區分開了。現在有一系列單獨的類別如ZoneId來處理特定時區,ZoneDateTime類別來表示某時區下的時間。這在Java8以前都是GregorianCalendar類別來做的。下面這個例子顯示如何把本時區的時間轉換成另一個時區的時間。 packagecom.shxt.demo02;importjava.time.LocalDateTime;importjava.time.ZoneId;importjava.time.ZonedDateT

在Java8中取得目前的時間戳記Instant類別有一個靜態工廠方法now()會傳回目前的時間戳,如下所示:packagecom.shxt.demo02;importjava.time.Instant;publicclassDemo16{publicstaticvoidmain(String[]args) {Instanttimestamp=Instant.now();System.out.println("Whatisvalueofthisinstant"+timestamp.t

Java8中取得今天的日期Java8中的LocalDate用來表示當天日期。和java.util.Date不同,它只有日期,不包含時間。當你只需要表示日期時就用這個類別。 packagecom.shxt.demo02;importjava.time.LocalDate;publicclassDemo01{publicstaticvoidmain(String[]args){LocalDatetoday=LocalDate.now();System.out.println("今天的日期:&q

Java8中如何使用預先定義的格式化工具去解析或格式化日期packagecom.shxt.demo02;importjava.time.LocalDate;importjava.time.format.DateTimeFormatter;publicclassDemo17{publicstaticvoidmain(String[]args){StringdayAfterTommorrow="201802055 ";LocalDateformatted=LocalDate.parse
