为什么Arrays.stream()不支持char []唯一的数组?


Answers:


31

正如伊兰所说,这不是唯一的失踪者。

BooleanStream将是无用的,一个ByteStream(如果它存在)可以作为一个被处理InputStream或转换成IntStream(如罐short),并且float可以作为一个来处理DoubleStream

由于char仍然无法表示所有字符(请参见链接),因此有点遗留。尽管大多数人无论如何都不必处理代码点,所以它看起来很奇怪。我的意思是您在使用时String.charAt()没有想到“这并非在所有情况下都有效”。

因此,有些事情被忽略了,因为它们并不那么重要。正如JB Nizet在链接的问题中所说:

设计者明确选择通过将原始流限制为3种类型来避免类和方法的爆炸式增长,因为其他类型(char,short,float)可以用它们较大的等价物(int,double)表示,而不会造成任何明显的性能损失。

原因BooleanStream将是无用的,因为您只有2个值,这极大地限制了操作。没有数学运算可做,您是否经常使用大量布尔值?


7
“一BooleanStream无用”:为什么?
glglgl

12
难道真的不合理的假设有人能需要做的,例如reduce(Boolean::logicalAnd)或者reduce(Boolean::logicalOr),在一个boolean[]?毕竟,方法logicalAndlogicalOr已经在Java中添加8,所以我可以做的这些归约操作Stream<Boolean>...顺便说一下,您可以流过char[]一样简单CharBuffer.wrap(array).chars()或者CharBuffer.wrap(array).codePoints(),这取决于你喜欢哪种语义。
Holger

2
@Holger仅因为Boolean::logicalAnd存在而已,并不一定保证存在BooleanStream。毕竟,这些可以在非流lambda情况下使用。我可以想像,有人会这样做reduce(Boolean::logicalAnd),但在任何情况下,有没有人需要做到这一点。
Kayaman

4
我看不出您要提出什么论据。以它的极端形式:“我可以想象有人会想做while (i < limit),但是在任何情况下都不需要做(使用分支和跳转汇编指令)”
亚历山大-莫妮卡

11
在我看来<Primitive>Stream,每个原始类型都没有的唯一原因是因为它会使API过度膨胀。正确的问题是“为什么在那里IntStream?” 不幸的答案是因为Java的类型系统不够充实,无法表达Stream<int>而没有使用的所有性能开销Integer。如果Java具有值类型,可以将值类型分配在堆栈上或直接内嵌在其他数据结构中,那么就不需要别的了Stream<T>
亚历山大-莫妮卡

32

当然,答案是“ 因为这就是设计师的决定 ”。没有技术原因CharStream不能存在。

如果需要证明理由,通常需要打开OpenJDK邮件列表*。JDK的文档不习惯证明为什么是什么就是为什么。

有人问

使用IntStream表示字符/字节流有点不方便。我们应该同时添加CharStream和ByteStream吗?

Java语言架构师Brian Goetz的回复说

简短的回答:不。

对于几乎从未使用过的这些表单,每个JDK占用100K +的空间都不值得。如果我们添加了这些,那么有人会要求short,float或boolean。

换句话说,如果人们坚持认为我们拥有所有原始专业化知识,那么我们将没有原始专业化知识。这将比现状更糟。

资源

他在别处也说过

如果您想将它们作为字符处理,则可以将它们轻松转换为字符。似乎没有足够重要的用例来拥有整个“另一组流”。(与Short,Byte,Float相同)。

资源

TL; DR:不值得维护费用。


*如果您感到好奇,我使用的Google查询是

site:http://mail.openjdk.java.net/ charstream

2
有人可以澄清他们的意思100K+ of JDK footprint吗?
yassin

3
@yassin有人必须编写代码。他估计流的每个专业化都超过100,000行代码
Michael

3
@BulgarSadykov有关“ 为什么X像Y的问题”这样的问题通常以基于观点的方式封闭,因为它不可能读懂原始作者的思想,而且除非它们碰巧出现,否则您得到的只是猜想。如果我问“如何使用Apache的HTTP客户端发送POST请求?”,熟悉该库的任何人都可以回答。为什么以这种方式设计库通常是无法回答的。我们真正能够回答这一问题的唯一原因是因为他们的谈话有公开记录。这就是我想用第一句话来理解的内容。
迈克尔

2
@BulgarSadykov还提到了有关C#的Eric Lippert的博客,这也使人想起了这个问题,但主题是“为什么不使用该语言实现Foo功能” stackoverflow.com/a/5588850/479251
Pac0

2
@BulgarSadykov完全不同意。再次,我重复示例问题“ 如何与Apache的HTTP客户端发送POST请求? ”。这个问题的答案显然不是以“ 因为这是设计师决定的 ” 开头。抱歉,我没有改变措词。
迈克尔

7

不仅char不支持数组。

只有3种原始流- IntStreamLongStreamDoubleStream

其结果是,Arrays有一个转换方法int[]long[]double[]以相应的原始流。

有对没有相应的方法boolean[]byte[]short[]char[]float[],因为这些原始类型没有相应的原始流。


4
“由于这些原始类型没有相应的原始流。” 那么后续问题将是“为什么”?
Federico klez Culloca

7
@FedericoklezCulloca 在这里
Eran

6

charString-存储UTF-16值的从属部分。Unicode符号(一个代码点)有时是一个替代字符。因此,任何使用char的简单解决方案都仅覆盖Unicode域的一部分。

有一段时间,char它有自己的权利成为公共类型。但是现在最好使用代码点IntStream。字符流无法直接处理代理对。

另一个比较平淡的原因是,JVM“处理器”模型使用int最小的“寄存器”,在这种int大小的存储位置中保留布尔值,字节,短裤和字符。为了不必膨胀Java类,请不要使用所有可能的复制变体。

不久的将来,人们可能期望允许原始类型用作通用类型参数,从而提供一个List<int>。然后我们可能会看到一个Stream<char>

目前最好避免char使用,并且可以使用java.text.Normalizer唯一的规范形式的代码点/ Unicode字符串。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.