Java 12:使用开关表达式进行映射
在本文中,我們將研究Java 12的新功能“ Switch Expressions”,以及如何與Java 12結合使用。
Stream::map操作和其他一些Stream操作。 了解如何使用流和開關表達式使代碼更好。
切換表達式
Java 12附帶了對“開關表達式”的“預覽”支持。 Switch Expression允許switch語句直接返回值,如下所示:
public String newSwitch( int day) { return switch (day) { case 2 , 3 , 4 , 5 , 6 -> "weekday" ; case 7 , 1 -> "weekend" ; default -> "invalid" ; } + " category" ; }用1調用此方法將返回“周末類別”。
這很棒,并使我們的代碼更短,更簡潔。 我們不必費心去掉顧慮,塊,易變的臨時變量或遺漏的情況/默認情況,這可能是良好的開關的情況。 只要看一下對應的舊開關示例,您就會明白我的意思:
public String oldSwitch( int day) { final String attr; switch (day) { case 2 , 3 , 4 , 5 , 6 : { attr = "weekday" ; break ; } case 7 , 1 : { attr = "weekend" ; break ; } default : { attr = "invalid" ; } } return attr + " category" ; }開關表達式是預覽功能
為了使Switch Expression在Java 12下工作,我們必須通過
編譯和運行應用程序時,都將“--enable-preview”作為命令行參數。 事實證明,這有些棘手,但希望它會隨著新IDE版本的發布和/或(如果Java將此功能作為完全受支持的功能)合并而變得更加容易。 IntelliJ用戶需要使用版本2019.1或更高版本。
在Stream :: map中切換表達式
開關表達式在Stream::map運算符中非常易于使用,尤其是與舊的開關語法相比時。 在以下示例中,我使用了Speedment Stream ORM和Sakila示例數據庫 。 Sakila數據庫包含有關電影,演員等的全部信息。
這是使用map()結合Switch Expression將電影語言ID( short )解碼為完整語言名稱( String )的流:
public static void main(String... argv) { try (Speedment app = new SakilaApplicationBuilder() .withPassword( "enter-your-db-password-here" ) .build()) { FilmManager films = app.getOrThrow(FilmManager. class ); List<String> languages = films.stream() .map(f -> "the " + switch (f.getLanguageId()) { case 1 -> "English" ; case 2 -> "French" ; case 3 -> "German" ; default -> "Unknown" ; } + " language" ) .collect(toList()); System.out.println(languages); } }這將在數??據庫中創建所有1000部電影的流,然后將每部電影映射到相應的語言名稱,并將所有這些名稱收集到一個列表中。 運行此示例將產生以下輸出(為簡潔起見,以下簡稱):
[英語,英語,…]
如果我們將使用舊的switch語法,則將獲得如下所示的內容:
... List<String> languages = films.stream() .map(f -> { final String language; switch (f.getLanguageId()) { case 1 : { language = "English" ; break ; } case 2 : { language = "French" ; break ; } case 3 : { language = "German" ; break ; } default : { language = "Unknown" ; } } return "the " + language + " language" ; }) .collect(toList()); ...或者,也許是這樣的:
... List<String> languages = films.stream() .map(f -> { switch (f.getLanguageId()) { case 1 : return "the English language" ; case 2 : return "the French language" ; case 3 : return "the German language" ; default : return "the Unknown language" ; } }) .collect(toList()); ...后一個示例簡短一些,但是重復了邏輯。
在Stream :: mapToInt中切換表達式
在此示例中,我們將基于電影的評分來計算有關分配分數的摘要統計信息。 根據我們自己的發明規模,限制越嚴格,得分越高:
IntSummaryStatistics statistics = films.stream() .mapToInt(f -> switch (f.getRating().orElse( "Unrated" )) { case "G" , "PG" -> 0 ; case "PG-13" -> 1 ; case "R" -> 2 ; case "NC-17" -> 5 ; case "Unrated" -> 10 ; default -> 0 ; }) .summaryStatistics(); System.out.println(statistics);這將產生以下輸出:
IntSummaryStatistics{count= 1000 , sum= 1663 , min= 0 , average= 1.663000 , max= 5 }在這種情況下,“開關表達式”與舊開關之間的差異并不大。 使用舊的開關,我們可以這樣寫:
IntSummaryStatistics statistics = films.stream() .mapToInt(f -> { switch (f.getRating().orElse( "Unrated" )) { case "G" : case "PG" : return 0 ; case "PG-13" : return 1 ; case "R" : return 2 ; case "NC-17" : return 5 ; case "Unrated" : return 10 ; default : return 0 ; } }) .summaryStatistics();在Stream :: collect中切換表達式
最后一個示例顯示了在收集器分組中使用switch表達式的情況。 在這種情況下,我們要計算某個最低年齡的人可以看多少部電影。 在這里,我們使用年齡最小的地圖作為鍵,將已計數的電影作為值。
Map<Integer, Long> ageMap = films.stream() .collect( groupingBy( f -> switch (f.getRating().orElse( "Unrated" )) { case "G" , "PG" -> 0 ; case "PG-13" -> 13 ; case "R" -> 17 ; case "NC-17" -> 18 ; case "Unrated" -> 21 ; default -> 0 ; }, TreeMap:: new , Collectors.counting() ) ); System.out.println(ageMap);這將產生以下輸出:
{ 0 = 372 , 13 = 223 , 17 = 195 , 18 = 210 }通過提供(可選) groupingBy地圖供應商TreeMap::new ,我們可以按年齡順序排列年齡。 為什么從13歲起就可以看到PG-13,而從17歲起就不能看到NC-17,而是從18歲起就看不到NC-17,但這不在本文的討論范圍之內。
摘要
我期待將Switch Expressions功能正式納入Java。 開關表達式有時可以替換許多流操作類型的lambda和方法引用。
翻譯自: https://www.javacodegeeks.com/2019/03/java-12-mapping-with-switch-expressions.html
總結
以上是生活随笔為你收集整理的Java 12:使用开关表达式进行映射的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 入豫备案在哪办理(入豫备案电话)
- 下一篇: 安卓编程c语言(安卓编程c)