方法引用
比如想得到艺术家的姓名,,Lambda表达式如下:
artist -> artist.getName()
使用方法引用后,代码如下:
Artist::getName
标准语法:Classname::methodName
元素顺序
如果集合本身就是无序的,由此生成的流也是无序的。HashSet就是一种无序的集合。
一些操作在有序的流上开销更大,调用unordered方法消除这种顺序就能解决该问题。大多数操作都是在有序流上效率更高。比如filter,map,reduce等。
使用并行流时,forEach方法不能保证元素是按顺序处理的。如果需要保证按顺序处理,应该使用forEachOrdered方法。
使用收集器
可以使用collect(toList()),在流中生成列表。显然,List是能想到的从流中生成的最自然的数据结构,但有时人们还希望从流生成其他值,比如Map或Set,或者你希望定制一个类将你想要的东西抽象出来。
这就是收集器,一种通用的,从流生成复杂值的结构。只要将它传给collect方法,所有的流就都可以使用它了。
转换成其他集合
使用toCollection,用定制的集合收集元素:
stream.collect(toCollection(TreeSet::new));
转换成值
找出成员最多的乐队
public Optional<Artist> biggestGroup(Stream<Artist> artists) {
Function<Artist,Long> getCount = artist -> artist.getMembers().count();
return artists.collect(maxBy(comparing(getCount)));
}
找出一组专辑上曲目的平均数
public double averageNumberOfTracks(List<Album> albums) {
return albums.stream()
.collect(averagingInt(album -> album.getTrackList().size()));
}
数据分块
image.png将艺术家组成的流分成乐队和独唱歌手两部分
public Map<Boolean, List<Artist>> bandsAndSolo(Stream<Artist> artists) {
return artists.collect(partitioningBy(artist -> artist.isSolo()));
}
使用方法引用将艺术家组成的Stream 分成乐队和独唱歌手两部分
public Map<Boolean, List<Artist>> bandsAndSoloRef(Stream<Artist> artists) {
return artists.collect(partitioningBy(Artist::isSolo));
}
数据分组
image.png数据分组是一种更自然的分割数据操作,与将数据分成ture 和false 两部分不同,可以使用任意值对数据分组。比如现在有一个由专辑组成的流,可以按专辑当中的主唱对专辑分组
public Map<Artist, List<Album>> albumsByArtist(Stream<Album> albums) {
return albums.collect(groupingBy(album -> album.getMainMusician()));
}
字符串
很多时候,收集流中的数据都是为了在最后生成一个字符串
使用流和收集器格式化艺术家姓名
String result =
artists.stream()
.map(Artist::getName)
.collect(Collectors.joining(", ", "[", "]"));
组合收集器
使用收集器计算每个艺术家的专辑数
public Map<Artist, Long> numberOfAlbums(Stream<Album> albums) {
return albums.collect(groupingBy(album -> album.getMainMusician(),
counting()));
}
使用收集器求每个艺术家的专辑名
public Map<Artist, List<String>> nameOfAlbums(Stream<Album> albums) {
return albums.collect(groupingBy(Album::getMainMusician,
mapping(Album::getName, toList())));
}
网友评论