JDK 8流和分组
我在JDK 8中的Stream-Powered Collections Functionality中介紹了將JDK 8的Streams與Java集合一起使用的強大功能。 我沒有在那篇文章中討論groupingBy Collector 減少操作的使用,因此在這篇文章中解決了分組問題。
這篇博文中的示例將演示如何將集合支持的流與groupingBy收集器組合在一起,以按提供的分類指定的組重新組織底層集合的數據。 這些示例基于我先前的文章JDK 8中的Stream-Powered Collections Functionality中描述的Movie類和Set of Movie類。
下一個代碼清單演示了如何使用簡單的語句將提供的Movie Set分組為電影等級(關鍵字) Map到具有該等級(值)的電影。 groupingBy收集器將此Map作為鍵類型(在這種情況下為MpaaRating )的映射提供給要分組的對象類型List (在此情況下為Movie )。
/*** Demonstrate use of JDK 8 streams and Collectors.groupingBy to* group movies by their MPAA ratings.*/ private static void demonstrateGroupingByRating() {final Map<MpaaRating, List<Movie>> moviesByRating =movies.stream().collect(groupingBy(Movie::getMpaaRating));out.println("Movies grouped by MPAA Rating: " + moviesByRating); }在剛剛顯示的示例中(以及在本文后面的示例中),靜態導入java.util.stream.Collectors.groupingBy允許我不需要使用Collectors類名來限制groupingBy調用的范圍。 這個簡單的代碼片段通過將電影的等級與返回的電影等級的Map映射鍵映射到與每個等級相關的電影List來將電影分組。 這是當提供的Movie set與我先前引用的帖子中的相同時的輸出示例。
根據MPAA分級的電影:{PG13 = [電影:盜夢空間(2010),Science_FICTION,PG13、13],R = [電影:肖申克的救贖(1994),DRAMA,R,1],PG = [電影:攻略失落的方舟(1981),動作,PG,31,電影:回到未來(1985),SCIENCE_FICTION,PG,49,電影:星球大戰:第五集–帝國反擊(1980),SCIENCE_FICTION,PG,12 ]}
剛剛展示的功能的一種特定用途是生成一個唯一鍵Map ,該鍵Map到Collection中的對象,并Map到具有該鍵的Collection對象。 例如,在需要通過map反復快速查找對象但在Set或List而不是在Map提供感興趣的對象時,這可能很有用。 假裝電影具有唯一的標題(它們僅適用于我的小型電影),那么可以如下面的代碼清單所示完成這些功能。
/*** Demonstrate use of JDK 8 streams and Collectors.groupingBy to* group movies by their title.*/ private static void demonstrateGroupingByTitle() {final Map<String, List<Movie>> moviesByTitle =movies.stream().collect(groupingBy(Movie::getTitle));out.println("Movies grouped by title: " + moviesByTitle); }假設標題對于原始集合中的每個電影都是唯一的,則上面的代碼將電影標題映射到僅包含該標題適用的電影的單元素List 。 任何希望按標題快速查找電影的客戶端都可以調用moviesByTitle.get(String).get(0)來獲取與該標題相對應的完整Movie對象。 接下來顯示使用我的簡單電影集進行此操作的輸出。
按標題分組的電影:{The Shawshank Redemption = [電影:The Shawshank Redemption(1994),DRAMA,R,1],《星球大戰:第五集–帝國反擊》 = [電影:星球大戰:第五集–帝國反擊Back(1980),SCIENCE_FICTION,PG,12],Back to the Future = [電影:回到未來(1985),SCIENCE_FICTION,PG,49],《奪寶奇兵》 [Ravies of the Lost Ark( 1981),ACTION,PG,31],Inception = [電影:Inception(2010),Science_FICTION,PG13,13]}
可以通過兩個不同的特征進行分組。 這允許將Collection按一個特征分組,然后將這些組中的每個分組按第二個特征進行子分組。 例如,以下代碼清單按等級然后按流派將電影分組。
/*** Demonstrate use of JDK 8 streams and cascaded groupingBy* to group movies by ratings and then by genres within ratings.*/ private static void demonstrateGroupingByRatingAndGenre() {final Map<MpaaRating, Map<Genre, List<Movie>>> moviesByRatingAndGenre =movies.stream().collect(groupingBy(Movie::getMpaaRating, groupingBy(Movie::getGenre)));out.println("Movies by rating and genre: " + moviesByRatingAndGenre); }剛顯示的代碼列表首先按等級將基礎電影分組,然后再次將每部電影與特定等級的分組進行分組,但是這次按類型進行分組。 換句話說,我們通過收視率和流派獲得了兩級電影。 接下來顯示我的一組簡單電影的輸出。
按等級和流派的電影:{PG13 = {SCIENCE_FICTION = [電影:盜夢空間(2010),Science_FICTION,PG13,13]}},R = {DRAMA = [電影:肖申克的救贖(1994),DRAMA,R,1]} ,PG = {SCIENCE_FICTION = [電影:回到未來(1985),Science_FICTION,PG,49,電影:《星球大戰:第五集–帝國反擊》(1980),Science_FICTION,PG,12],ACTION = [電影:奪寶奇兵(1981),ACTION,PG,31]}}
通過groupingBy收集器,可以輕松地將List或Set元素分組為映射,并以分組特征為鍵,并將屬于List中每個組的對象與該分組特征鍵相關聯。 這提供了Map所有優點,包括使用JDK 8中引入的一些方便的Map方法。
翻譯自: https://www.javacodegeeks.com/2015/03/jdk-8-streams-and-grouping.html
總結
- 上一篇: 投资能力备案怎么填(投资能力备案)
- 下一篇: 给linux分区时找不到用于efi(给l