数据分块/分组
// partitioningBy接受一个流,并将其按boolean分成两部分
public Map<Boolean, List<Artist>> bandsAndSolo(Stream<Artist> artists) {
return artists.collect(partitioningBy(artist -> artist.isSolo()));
}
// groupingBy类似SQL中的group by操作
public Map<Artist,List<Album>> albumsByArtist(Stream<Album> albums){
return albums.collect(groupingBy(album->album.getMainMusician()));
}
// Collectors.joining收集流中的值,该方法可以方便地从一个流中得到一个字符串,允许用户提供分隔符(分隔元素)、前缀和后缀
String result = list.stream().collect(Collectors.joining(","));
组合收集器
// 计算每个艺术家的专辑数
public Map<Artist,Long> numberOfAlbums(Stream<Album> albums){
return albums.collect(groupingBy(album -> album.getMainMusician(),counting()));
}
groupingBy先将元素分块,每块都与分类函数getMainMusician提供的键值相关联,然后使用下游的另一个收集器收集每块中的元素,最后将结果映射为一个Map。
// 计算每个艺术家的专辑名
public Map<Artist,List<String>> nameOfAlbums(Stream<Album> albums){
return albums.collect(groupingBy(Album::getMainMusician,mapping(Album::getName,toList())));
}
下游收集器:两个例子中我们都用到了第二个收集器,用以收集最终结果的一个子集。收集器是生成最终结果的一剂配方,下游收集器则是生成部分结果的配方,主收集器中会用到下游收集器。