[翻譯] Java 8 取出 Collection element 的方式

看板java作者 (痞子軍團團長)時間11年前 (2013/04/03 12:46), 編輯推噓0(006)
留言6則, 3人參與, 最新討論串1/4 (看更多)
※ [本文轉錄自 Translate-CS 看板 #1HMxDUIX ] 作者: PsMonkey (痞子軍團團長) 看板: Translate-CS 標題: [翻譯] Java 8 取出 Collection element 的方式 時間: Wed Apr 3 12:42:59 2013 原文網址:http://www.javacodegeeks.com/2013/03/ extracting-the-elements-of-the-java-collection-the-java-8-way.html 譯文網址:http://blog.dontcareabout.us/2013/04/java-8-collection-element.html BBS 使用 markdown 格式撰寫 譯文中的 Collection,代表 Collection API 或是屬於 Collection 的各個 class(List、Map...)。 如果是 collection,則代表某個 Collection 的 instance。 ______________________________________________________________________ 我們都廣泛使用 Collection, 像是 `List`、`Map` 以及延伸的 class。 每次我們用的時候,我們都得掃遍整個 collection 去找到某些 element、 更新它們、或是找出某個條件下不同的 element。 就像下面這個 `Person` 的 `List`: List<Person> personList = new ArrayList<>(); personList.add(new Person("Virat", "Kohli",22)); personList.add(new Person("Arun", "Kumar",25)); personList.add(new Person("Rajesh", "Mohan", 32)); personList.add(new Person("Rahul", "Dravid", 35)); 要找出 `Person` 的年齡大於 30 的 instance,我們會這樣作: List<Person> olderThan30OldWay = new ArrayList<>(); for ( Person p : personList){ if ( p.age >= 30){ olderThan30OldWay.add(p); } } System.out.println(olderThan30OldWay); 就會得到這樣的輸出結果: [Rajesh Mohan, 32, Rahul Dravid, 35] 程式碼是很好寫,但會不會有點囉唆、尤其是迴圈的部份? 為甚麼我們得要有迴圈呢? 如果有 API 可以掃描內容、然後給我們最終結果, 例如我們給一個 `List`、然後用一串 method 之後 就可以取得我們想要的 `List` 結果? 有的,在 Scala、Groovy 這種有支援 closure、 也支援內部迴圈的語言就有可能做到。 但是有給 Java 開發人員的解決方案嗎? 有的,這個問題在導入 [Lambda Expression(closure)] 後, 利用 lambda expression 來 [加強 Collection API][sotc3],就可以解決。 不過壞消息是,這會是 Java 8 的一部分, [需要一點時間]才會變成主流的開發方式。 [Lambda Expression(closure)]: http://openjdk.java.net/projects/lambda/ [sotc3]: http://cr.openjdk.java.net/~briangoetz/lambda/sotc3.html [需要一點時間]: http://openjdk.java.net/projects/jdk8/milestones 在上面的情境中使用 Java 8 的強化功能 ==================================== 正如我知前所說,Collection API 正在補強以支援 lambda expression, 你可以在[這篇文章][sotc3]中了解更多內容。 JDK 團隊並不是把所有新的 API 加到 Collection 當中, 而是創造了一個新的概念 `Stream`, 並且把大部分的 API 加到那個 class 當中。 `Stream` 是 element 的序列,在建立時從 collection 取得。 要了解更多 `Stream` 的起源,請參考[這篇文章][sotc3]。 要實作這個範例,我開始使用 Java 8 的強化功能、一些新的 API: `stream()`、`filter()`、`collect()`、`Collectior.toCollection()`。 * [stream()]:collection 用這個 API 可以建立一個 [Stream] 的 instance。 * [filter()]:這個 method 接收一個 會回傳 boolean 值的 lambda expression , 這個 lambda expression 會替換成 [Predicate] class 的實作。 * [collect()]:有兩個 overloaded 的版本。我在這邊用其中一個, 可以取得 [Collector] 的 instance。 這個 method 會取得 stream 的內容然後建立另一個 collection, 建立的邏輯在 [Collector] 當中定義。 * [Collectors.toCollection()][toCollection()]: [Collectors] 是 [Collector] 的 factory(pattern)。 [toCollection()] 需要一個可以回傳任何 Collection class instance 的 lambda expression / method reference。 [stream()]: http://download.java.net/lambda/b81/docs/api/ java/util/Collection.html#stream() [Stream]: http://download.java.net/lambda/b81/docs/api/ java/util/stream/Stream.html [filter()]: http://download.java.net/lambda/b81/docs/api/ java/util/stream/Stream.html#filter(java.util.function.Predicate) [Predicate]: http://download.java.net/lambda/b81/docs/api/ java/util/function/Predicate.html [collect()]: http://download.java.net/lambda/b81/docs/api/ java/util/stream/Stream.html#collect(java.util.stream.Collector) [Collector]: http://download.java.net/lambda/b81/docs/api/ java/util/stream/Collector.html [toCollection()]: http://download.java.net/lambda/b81/docs/api/ java/util/stream/Collectors.html #toCollection(java.util.function.Supplier) [Collectors]: http://download.java.net/lambda/b81/docs/api/ java/util/stream/Collectors.html 簡單介紹要用的 API 之後,讓我來展示一下跟第一個範例等意的程式碼: List<Person> olderThan30 = //Create a Stream from the personList personList.stream(). //filter the element to select only those with age >= 30 filter(p -> p.age >= 30). //put those filtered elements into a new List. collect(Collectors.toCollection(() -> new ArrayList<Person>())); System.out.println(olderThan30); 上面的程式碼使用內部迴圈以及 lambda expression 讓它看起來直覺、簡潔、還可以舒緩眼睛不適。 (譯註:我承認最後一個是惡搞亂翻的 [逃]) 如果你不熟悉 lambda expression 的想法, 可以看一下我[之前寫的文章],裡頭有簡單的介紹。 [之前寫的文章]: http://blog.sanaulla.info/2013/03/11/ using-lambda-expression-to-sort-a-list-in-java-8 -using-netbeans-lambda-support/ -- 錢鍾書: 說出來的話 http://www.psmonkey.org 比不上不說出來的話 Java 版 cookcomic 版 只影射著說不出來的話 and more...... -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 114.25.29.173 ※ 編輯: PsMonkey 來自: 114.25.29.173 (04/03 12:46) ※ 發信站: 批踢踢實業坊(ptt.cc) ※ 轉錄者: PsMonkey (114.25.29.173), 時間: 04/03/2013 12:46:27

04/03 14:04, , 1F
我在寫python的時候~就覺得java很不直覺(哀)
04/03 14:04, 1F

04/03 14:32, , 2F
`filter`不是接收一個lambda ,回傳一個boolean
04/03 14:32, 2F

04/03 14:36, , 3F
而是接收"回傳值為boolean的lambda"
04/03 14:36, 3F

04/03 14:39, , 4F
真正模糊焦點的是`Stream` 這東西根本不應該存在...= =
04/03 14:39, 4F

04/03 14:46, , 5F
希望SE9會把它@Deprecated就是了
04/03 14:46, 5F
感謝指正 ※ 編輯: PsMonkey 來自: 114.25.29.173 (04/03 15:21)

04/05 17:22, , 6F
我也以為會像是python的寫法 沒像到搞的這麼複雜= ="
04/05 17:22, 6F
文章代碼(AID): #1HMxGZiP (java)
討論串 (同標題文章)
文章代碼(AID): #1HMxGZiP (java)