在 Java 8 中,是否有 ByteStream 类?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32459683/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
In Java 8, is there a ByteStream class?
提问by sdgfsdh
Java 8 provides Stream<T>
specializations for double
, int
and long
: DoubleStream
, IntStream
and LongStream
respectively. However, I could not find an equivalent for byte
in the documentation.
Java的8提供Stream<T>
专业化的double
,int
和long
:DoubleStream
,IntStream
和LongStream
分别。但是,我byte
在文档中找不到对应的 for 。
Does Java 8 provide a ByteStream
class?
Java 8 是否提供ByteStream
类?
采纳答案by Tunaki
No, it does not exist. Actually, it was explicitly not implemented so as not to clutter the Stream API with tons of classes for every primitive type.
不,它不存在。实际上,它没有被明确地实现,以免每个原始类型的大量类使 Stream API 混乱。
Quoting a mailfrom Brian Goetz in the OpenJDK mailing list:
在 OpenJDK 邮件列表中引用Brian Goetz的一封邮件:
Short answer: no.
It is not worth another 100K+ of JDK footprint each for these forms which are used almost never. And if we added those, someone would demand short, float, or boolean.
Put another way, if people insisted we had all the primitive specializations, we would have no primitive specializations. Which would be worse than the status quo.
简短的回答:没有。
对于这些几乎从未使用过的表单,每个 JDK 占用的 100K+ 空间都不值得。如果我们添加这些,有人会要求 short、float 或 boolean。
换句话说,如果人们坚持我们拥有所有原始专业,我们就没有原始专业。这将比现状更糟糕。
回答by Tagir Valeev
Most of the byte-related operations are automatically promoted to int. For example, let's consider the simple method which adds a byte
constant to each element of byte[]
array returning new byte[]
array (potential candidate for ByteStream
):
大多数与字节相关的操作都会自动提升为 int。例如,让我们考虑一个简单的方法,它byte
向byte[]
数组的每个元素添加一个常量,返回新byte[]
数组( 的潜在候选者ByteStream
):
public static byte[] add(byte[] arr, byte addend) {
byte[] result = new byte[arr.length];
int i=0;
for(byte b : arr) {
result[i++] = (byte) (b+addend);
}
return result;
}
See, even though we perform an addition of two byte
variables, they are widened to int
and you need to cast the result back to byte
. In Java bytecode most of byte
-related operations (except array load/store and cast to byte) are expressed with 32-bit integer instructions (iadd
, ixor
, if_icmple
and so on). Thus practically it's ok to process bytes as ints with IntStream
. We just need two additional operations:
看,即使我们执行了两个byte
变量的相加,它们也被扩展为int
并且您需要将结果转换回byte
。在Java字节码最的byte
-相关操作(除了阵列加载/存储和转换为字节)与32位整数指示(表示iadd
,ixor
,if_icmple
等等)。因此实际上将字节作为整数处理是可以的IntStream
。我们只需要两个额外的操作:
- Create an
IntStream
frombyte[]
array (widening bytes to ints) - Collect an
IntStream
tobyte[]
array (using(byte)
cast)
- 创建一个
IntStream
frombyte[]
数组(将字节扩展为整数) - 收集
IntStream
到byte[]
数组(使用(byte)
强制转换)
The first one is really easy and can be implemented like this:
第一个非常简单,可以像这样实现:
public static IntStream intStream(byte[] array) {
return IntStream.range(0, array.length).map(idx -> array[idx]);
}
So you may add such static method to your project and be happy.
因此,您可以将这样的静态方法添加到您的项目中并感到高兴。
Collecting the stream into byte[]
array is more tricky. Using standard JDK classes the simplest solution is ByteArrayOutputStream
:
将流收集到byte[]
数组中更加棘手。使用标准 JDK 类最简单的解决方案是ByteArrayOutputStream
:
public static byte[] toByteArray(IntStream stream) {
return stream.collect(ByteArrayOutputStream::new, (baos, i) -> baos.write((byte) i),
(baos1, baos2) -> baos1.write(baos2.toByteArray(), 0, baos2.size()))
.toByteArray();
}
However it has unnecessary overhead due to synchronization. Also it would be nice to specially process the streams of known length to reduce the allocations and copying. Nevertheless now you can use the Stream API for byte[]
arrays:
然而,由于同步,它有不必要的开销。此外,最好专门处理已知长度的流以减少分配和复制。尽管如此,现在您可以将 Stream API 用于byte[]
数组:
public static byte[] addStream(byte[] arr, byte addend) {
return toByteArray(intStream(arr).map(b -> b+addend));
}
My StreamExlibrary has both of these operations in the IntStreamEx
class which enhances standard IntStream
, so you can use it like this:
我的StreamEx库在IntStreamEx
增强标准的类中具有这两个操作IntStream
,因此您可以像这样使用它:
public static byte[] addStreamEx(byte[] arr, byte addend) {
return IntStreamEx.of(arr).map(b -> b+addend).toByteArray();
}
Internally toByteArray()
method uses simple resizable byte bufferand specially handlesthe case when the stream is sequential and target size is known in advance.
回答by Kaplan
if you don't have aByteStream, build one
如果您没有ByteStream,请构建一个
Stream.Builder<Byte> builder = Stream.builder();
for( int i = 0; i < array.length; i++ )
builder.add( array[i] );
Stream<Byte> stream = builder.build();
...where array can be of type byte[]
or Byte[]
...其中数组可以是类型byte[]
或Byte[]