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

方法引用

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());
})

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值