JDK 8流和分组

本文探讨了如何使用JDK 8的Stream API和Collectors.groupingBy()方法将集合数据按指定标准分组。通过示例展示了如何按电影等级、标题或等级加类型对电影集合进行分组,强调了这一功能在快速查找和组织数据时的实用性。
摘要由CSDN通过智能技术生成

我在JDK 8中的Stream-Powered Collections Functionality中介绍了将JDK 8StreamsJava集合一起使用的强大功能。 我没有在那篇文章中讨论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 ,该键MapCollection中的对象,并Map到具有该键的Collection对象。 例如,在需要通过map反复快速查找对象但在SetList而不是在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收集器,可以轻松地将ListSet元素分组为映射,并以分组特征为键,并将属于List中每个组的对象与该分组特征键相关联。 这提供了Map所有优点,包括使用JDK 8中引入的一些方便的Map方法。

翻译自: https://www.javacodegeeks.com/2015/03/jdk-8-streams-and-grouping.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值