方法引用
artist -> artist.getName()
可以被以下代码替换
Artist::getName
标准语法为Classname::methodName
构造函数也支持
Artist::new
String[]::new
收集器
一种通用的、从流生成复杂值的结构。只要将它传给collect 方法,所有
的流就都可以使用它了。
1.转换成其他集合 toList,toSet 和toCollection
stream.collect(toCollection(TreeSet::new));
2.转换成值 maxBy,minBy,averagingInt,summingInt
maxBy 和minBy 允许用户按某种特定的顺序生成一个值
找出成员最多的乐队
public Optional<Artist> biggestGroup(Stream<Artist> artists) {
Function<Artist,Long> getCount = artist -> artist.getMembers().count();
return artists.collect(maxBy(comparing(getCount)));
}
averagingInt 方法接受一个Lambda 表达式作参数,将流中的元素转换成一个整数,然后再计算平均数
public double averageNumberOfTracks(List<Album> albums) {
return albums.stream()
.collect(averagingInt(album -> album.getTrackList().size()));
}
summingInt计算总和
3.数据分块 partitioningBy
收集器partitioningBy,它接受一个流,并将其分成两部分,它使用Predicate 对象判断一个元素应该属于哪个部分,并根据布尔值返回一个Map 到列表
使用主唱对专辑分组
public Map<Artist, List<Album>> albumsByArtist(Stream<Album> albums) {
return albums.collect(groupingBy(album -> album.getMainMusician()));
}
4. 数据分组 groupingBy
可以使用任意值对数据分组
使用主唱对专辑分组
public Map<Artist, List<Album>> albumsByArtist(Stream<Album> albums) {
return albums.collect(groupingBy(album -> album.getMainMusician()));
}
5. 字符串 joining
该方法可以方便地从一个流得到一个字符串,允许用户提供分隔符(用以分隔元素)、前缀和后缀。
使用流和收集器格式化艺术家姓名
String result =
artists.stream()
.map(Artist::getName)
.collect(Collectors.joining(", ", "[", "]"));
5.组合收集器 counting,mapping
使用counting收集器计算每个艺术家的专辑数
public Map<Artist, Long> numberOfAlbums(Stream<Album> albums) {
return albums.collect(groupingBy(album -> album.getMainMusician(),
counting()));
}
mapping 收集器 告诉groupingBy将它的值做映射,生成最终结果。
使用收集器求每个艺术家的专辑名
public Map<Artist, List<String>> nameOfAlbums(Stream<Album> albums) {
return albums.collect(groupingBy(Album::getMainMusician,
mapping(Album::getName, toList())));
}
其他
computeIfAbsent
该方法接受一个Lambda 表达式,值不存在时使用该Lambda 表达式计算新值
使用computeIfAbsent 缓存
如果name不存在就从数据库读取
public Artist getArtist(String name) {
return artistCache.computeIfAbsent(name, this::readArtistFromDB);
}
foreach
该方法接受一个BiConsumer 对象为参数(该对象接受两个参数,返回空),通过内部迭代编写出易于阅读的代码
使用内部迭代遍历Map 里的值
Map<Artist, Integer> countOfAlbums = new HashMap<>();
albumsByArtist.forEach((artist, albums) -> {
countOfAlbums.put(artist, albums.size());
})