在Java8中,是否存在ByTestStream类?
Java8分别为在Java8中,是否存在ByTestStream类?,java,java-8,byte,java-stream,boxing,Java,Java 8,Byte,Java Stream,Boxing,Java8分别为double、int和long提供Stream、IntStream和LongStream的。但是,我在中找不到与byte等效的 Java8是否提供了ByTestStream类 不,它不存在。实际上,它并没有显式地实现,以避免流API中每种基本类型都有大量的类 引用OpenJDK邮件列表中Brian Goetz的话: 简短回答:没有 对于这些表单,每一个都不值得再增加10万多JDK内存 它们几乎从未被使用过。如果我们加上这些,就会有人 要求短、浮或布尔 换句话说,如果人们坚持我们
double
、int
和long
提供Stream
、IntStream
和LongStream
的。但是,我在中找不到与byte
等效的
Java8是否提供了ByTestStream
类 不,它不存在。实际上,它并没有显式地实现,以避免流API中每种基本类型都有大量的类
引用OpenJDK邮件列表中Brian Goetz的话:
简短回答:没有
对于这些表单,每一个都不值得再增加10万多JDK内存
它们几乎从未被使用过。如果我们加上这些,就会有人
要求短、浮或布尔
换句话说,如果人们坚持我们拥有所有原始的
专门化,我们将没有原始的专门化。哪个
会比现状更糟
大多数字节相关的操作都会自动升级到int。例如,让我们考虑一个简单的方法,它给<代码>字节[][COD]>数组中的每个元素添加一个<代码>字节>代码>常量数组,返回新的<代码>字节[]/Cord>数组(潜在的候选代码>字节流< /代码>):
请看,即使我们执行两个byte
变量的加法,它们也会扩展到int
,您需要将结果转换回byte
。在Java字节码中,大多数与字节相关的操作(数组加载/存储和转换为字节除外)都用32位整数指令(iadd
、ixor
、if\u icmple
等)表示。因此,实际上可以使用IntStream
将字节作为int进行处理。我们只需要两个额外的操作:
- 从
byte[]
数组创建IntStream
(将字节扩展为int)
- 收集
IntStream
到byte[]
数组(使用(byte)
cast)
第一个非常简单,可以这样实现:
public static IntStream intStream(byte[] array) {
return IntStream.range(0, array.length).map(idx -> array[idx]);
}
public static byte[] addStreamEx(byte[] arr, byte addend) {
return IntStreamEx.of(arr).map(b -> b+addend).toByteArray();
}
因此,您可以将这种静态方法添加到您的项目中,并感到高兴
将流收集到byte[]
数组中更为棘手。使用标准JDK类,最简单的解决方案是ByteArrayOutputStream
:
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;
}
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();
}
但是,由于同步,它有不必要的开销。另外,最好专门处理已知长度的流,以减少分配和复制。不过,现在您可以将流API用于字节[]
数组:
public static byte[] addStream(byte[] arr, byte addend) {
return toByteArray(intStream(arr).map(b -> b+addend));
}
My library在类中具有这两种操作,增强了standardIntStream
,因此您可以这样使用它:
public static IntStream intStream(byte[] array) {
return IntStream.range(0, array.length).map(idx -> array[idx]);
}
public static byte[] addStreamEx(byte[] arr, byte addend) {
return IntStreamEx.of(arr).map(b -> b+addend).toByteArray();
}
在内部toByteArray()
方法使用简单的可调整大小,并且流是连续的,并且目标大小是预先知道的。如果没有ByTestStream,则构建一个
Stream.Builder=Stream.Builder();
for(int i=0;i
…其中数组的类型可以是byte[]
或byte[]
我喜欢这个解决方案,因为它在运行时从byte[]
执行,
而不是构建一个集合,然后从集合中进行流式处理。
我相信这只是对流一次执行一个字节
byte [] bytes =_io.readAllBytes(file);
AtomicInteger ai = new AtomicInteger(0);
Stream.generate(() -> bytes[ai.getAndIncrement()]).limit(bytes.length);
但是,由于AtomicInteger的同步瓶颈,这相当慢,所以请返回命令循环 改用com.google.common.primitives.Bytes.asList(byte[]).stream()。这能回答您的问题吗bas1.write(bas2.toByteArray(),0,bas2.size())
是一个不必要的复杂合并。首先,toByteArray()
总是返回大小合适的数组,因此不需要,0,2.size()。数组的大小总是适当的,原因是它总是返回一个新分配的数组。如果您想避免这种开销,请考虑使用<代码> BAOS.Wruteto(BaOS1)< /C> >,这更短和更有效。顺便说一下,在编写一个单代码>字节到<代码> OuttoStuts<代码>时,不需要从“代码> int <代码> > <代码>字节>代码>。因此,ByteArrayOutputStream::write
作为累加器函数就足够了。@Holger,writeTo
和write(byte[])
都声明抛出一个IOException
,因此您需要一个显式的try-catch。我刚刚选择了最短的版本(write(byte[],int,int)
不会抛出-疯狂,我知道)writeTo
确实会更有效率。至于显式演员阵容,我不记得了。也许我认为这样的版本会更清晰。当然,writeTo
需要一个try…catch
,所以{try{baos2.writeTo(baos1);}catch(IOException x){}
不比baos1.write(baos2.toByteArray(),0,baos2.size())
短,但它并没有显著地大(但效率更高)writeTo
必须声明IOException
,因为您可以将任意OutputStream
作为参数传递。write(byte[])
方法未被覆盖,因此不幸的是,它具有常规的OutputStream.write(byte[])
签名。提醒我…在一个32位的位置上每个存储8位都需要很大的空间,不是吗?真的吗?字节流“几乎从不”使用?我想知道那个家伙生活在哪个星球上,因为在现实世界中字节流无处不在。@augurar你必须问清楚:-)我的印象是大多数开发人员熟悉的字节流更多的是基于ByteArrayInputStream
/ByteArrayOutputStream
(用于I/O操作、批量数据处理等)。这些对象在概念上与Java 8 Stream API的Stream
s非常不同,后者用于函数式编程。我与@augurar合作。有