为什么java 8没有在Collection中实现基本的集合函数?

时间:2015-10-10 14:34:27

标签: java list collections java-8 java-stream

使用java 8,现在我们可以使用java.util.Collection.stream来执行一些集合基本功能,例如filtermapcollectanyMatch

问题是当你有一个Collection并且你必须使用其中的一些函数时,代码会变得有点难看,例如:

List<String> ids = this.getFriends(userId).stream().map(Friend::getFriendUserId).collect(Collectors.toList())

在这种情况下,我有一个List<Friend>,我想要一个List<String>,其中会填充第一个列表中每个项目的friendId。

我认为代码可能是这样的:

List<String> ids = this.getFriends(userId).map(Friend::getFriendUserId);

这当然更具可读性,也更干净,但无效,因为List无法理解消息地图。我无法理解在Java 8中实现这个问题会是什么问题,为什么他们决定强制每次都转换为Stream,在某些情况下我们会将其转换回Collection就像这种情况一样。

1 个答案:

答案 0 :(得分:2)

摆脱.stream()非常简单。只需更新您的API即可返回流,而不是集合。同样使用复数名词命名您的方法返回流。因此,更换

会更好
public List<Friend> getFriends(String userId) { ... }

使用

public Stream<Friend> friends(String userId) { ... }

此方案在JDK中广泛使用。示例:BufferedReader.lines()Random.ints()ZipFile.entries()String.chars()等等(更多内容见JDK-9)。

您可以做的第二件事是静态导入Collectors

import static java.util.stream.Collectors.*;

这会将Collectors.toList()缩短为简单toList()

List<String> ids = this.friends(userId).map(Friend::getFriendUserId).collect(toList());

已经短得多了。

最后,您应该考虑将结果流收集到List中是否真的有必要。有时它是合理的,但通常它只是在Java-8之前思考,就像你需要集合中的所有内容一样。例如,如果要使用此列表迭代它,为什么不使用Stream.forEach()迭代流本身?