为什么Java Stream.count()返回一个long类型?

41

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

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

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

但是为什么Java中的stream.count()会返回一个long而不是一个int呢?


11
为什么可以从足够小的长整型转换为整型,但无法从溢出的整型转换回长整型,因此应该返回一个整型? - tobias_k
5
处理流数据时,通常数据量非常大,这也是采用流式处理的原因。如果将长整型转换为整型,当数字很大时会失去精度。 - Minh Kieu
3
因为“long”比“int”更长。 - ACV
3个回答

23
1996年初推出Java时,普通PC只有8到16 MB的内存。由于数组和集合与内存大小密切相关,因此使用int表示元素计数似乎很自然,因为它足以寻址4 GB大小的int数组,这个大小即使对于1996年的硬盘来说也是巨大的,更别提RAM了。因此,在当时,使用long而不是int表示集合大小似乎是浪费的。
尽管int大小有时可能是一个限制因素,但Java设计师不能将其更改为long,因为这将是一个破坏性的变化。
与Java集合不同,流可能具有潜在的无限数量的元素,并且它们不带任何兼容性考虑因素。因此,使用long及其更广泛的值范围似乎是一个非常合理的选择。

一些Java集合(如LinkedList)可以包含潜在的无限数量的元素,即使它们的“size”会报告错误。 - ooxi

22

这个声明

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())时,我发现一个问题。它只是简单地计数,而没有处理业务逻辑。 - user14734781

22

它是Java支持的最大的64位原始值,所以就选用了它。

另一种方法将涉及两个计数:

countLong/countInt

那看起来会非常奇怪。

int 可以放在 long 里,但反过来就不行。你想用 int 做什么,都可以放在 long 里面,所以为什么需要提供两个呢?


2
如果我想节省内存怎么办?例如,在长字符串中计算字符数,每个字符不会超过Integer.MAX。在这种情况下使用Long而不是Integer会浪费内存。 - MasterJoe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接