函数式编程 高级集合类和收集器

来源:互联网 发布:python ide eclipse 编辑:程序博客网 时间:2024/06/05 15:27

方法引用

artist -> artist.getName()

可以被以下代码替换

Artist::getName

标准语法为Classname::methodName

构造函数也支持

Artist::newString[]::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());})

0 0
原创粉丝点击