【问题标题】:Why does not java 8 implement basic collection functions in Collection? [duplicate]为什么java 8没有在Collection中实现基本的collection函数? [复制]
【发布时间】:2016-01-08 09:32:30
【问题描述】:

有了java 8,现在我们可以使用java.util.Collection.stream来做一些收集基本功能,例如filtermapcollectanyMatch等。

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

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

在这种情况下,我有一个List&lt;Friend&gt;,我希望有一个List&lt;String&gt; 填充第一个列表中每个项目的friendId。

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

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

这当然更易读也更干净,但由于List 不理解消息映射而无效。我不明白在 Java 8 中实现这个会有什么问题,为什么他们决定每次都强制转换为Stream,而在某些情况下,我们又将它转换回Collection,就像在这种情况下一样.

【问题讨论】:

  • 主要原因是在流行的接口上添加(默认)方法很危险,因为它可能会破坏一些子类型。很可能有人有一个 List 的子类型,有自己的map 方法;如果在 java 8 中添加了List.map,它将不会在 java 8 下编译。
  • 这就是为什么他们在向 Collections API 添加方法时非常保守。仍然有关于破损的投诉。
  • @bayou.io 好吧,这很好,我认为你应该把它写成一个。

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


【解决方案1】:

摆脱.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() 来迭代流本身呢?

【讨论】:

  • 我不同意这种观点; List 仍然是一个非常有用的概念;我们不能再猜测程序员使用 List 的选择。即使Stream 在用例中更好,从某些象牙塔的角度来看,我们也不能责怪程序员使用List,如果它更好地模拟问题,从他的角度来看。毕竟,有一种计算机语言是为程序员服务的。
  • 你有你的观点,但我同意@bayou.io 的评论,因为我不会改变我所有的模型..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-10
  • 2013-02-13
  • 2011-02-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多