在Java8中,是否存在ByTestStream类?

在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内存 它们几乎从未被使用过。如果我们加上这些,就会有人 要求短、浮或布尔 换句话说,如果人们坚持我们

Java8分别为
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在类中具有这两种操作,增强了standard
IntStream
,因此您可以这样使用它:

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合作。有