【问题标题】:Why does java stream.count() return a long?为什么 java stream.count() 返回一个 long?
【发布时间】:2017-06-20 19:01:19
【问题描述】:

为什么stream.count() 不返回int

我知道我可以通过强制转换轻松地将 long 转换为 int

return (int) players.stream().filter(Player::isActive).count();

但是为什么 java stream.count() 会返回 long 而不是 int

【问题讨论】:

  • 如果您可以轻松地将足够小的 long 转换为 int,而不是从溢出的 int 转换回 long,为什么它要返回 int?
  • 当你处理流时,通常它会非常大,因此是流的原因。如果数字很大,将 long 转换为 int 将失去精度。
  • 因为longint

标签: java java-8 java-stream


【解决方案1】:

当 Java 于 1996 年初问世时,普通 PC 有 8 到 16 Mb 的内存。由于数组和集合都与内存大小密切相关,因此使用int 表示元素计数似乎很自然,因为它足以处理大小为 4Gb 的ints 数组——即使对于1996 年,更不用说 RAM。因此,使用 long 而不是 int 来获取集合大小在当时似乎很浪费。

虽然int 的大小有时可能是一个限制因素,但Java 设计人员不能将其更改为long,因为这将是一个重大更改。

与 Java 集合不同,流可能具有无限数量的元素,并且它们不考虑兼容性。因此,使用具有更广泛值范围的long 似乎是一个非常合理的选择。

【讨论】:

  • 一些 Java 集合也可能包含无限数量的元素(如 LinkedList),即使它们的 size 会被报告错误。
【解决方案2】:

因为它是 java 拥有的最大的 64 位原始值。 另一种方法是 两个 计数:

countLong/countInt

那看起来真的很奇怪。

int 适合long,但反之则不然。你想用 int 做的任何事情都可以放在 long 中,那么为什么需要同时提供两者呢?

【讨论】:

  • 如果我想节省内存怎么办?前任。计算一个长字符串中的字符数,知道每个字符出现的次数永远不会超过 Integer.MAX。在这种情况下使用 Long 而不是 Integer 会浪费内存。
【解决方案3】:

此声明

players.stream().filter(Player::isActive).count(); 

相当于:

players.stream().filter(Player::isActive).collect(Collectors.counting());

这仍然返回一个long,因为Collectors.counting()被实现为

reducing(0L, e -> 1L, Long::sum)

返回int 可以通过以下方式完成:

players.stream().filter(Player::isActive).collect(Collectors.reducing(0, e -> 1, Integer::sum));

此表格可用于groupingBy声明

Map<Player, Integer> playerCount = players.stream().filter(Player::isActive).collect(Collectors.groupingBy(Function.identity(), Collectors.reducing(0, e -> 1, Integer::sum)));

【讨论】:

  • 我在使用 .count(); 时发现了一个问题;而不是 .collect(Collectors.counting());。它在不处理业务逻辑的情况下进行简单计数
猜你喜欢
  • 2011-12-20
  • 1970-01-01
  • 1970-01-01
  • 2013-06-09
  • 1970-01-01
  • 1970-01-01
  • 2016-09-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多