Java8:如何流式处理int数组、提取低位字节和创建字节数组

Java8:如何流式处理int数组、提取低位字节和创建字节数组,java,java-stream,Java,Java Stream,为了连接两个库,我需要将包含字节的int[]数组转换为只包含低字节的byte[]数组。(我需要用0xFF屏蔽int,并将它们存储在byte[]数组中。)我只能找到如何在转换int的所有4个字节时执行此操作的示例,我不需要这些示例 作为一个练习,我希望在纯Java8中使用一些简短而高效的代码(即,没有外部库、调用或SOUP的有效Java8代码)。我尝试使用streams,但找不到有效的map();例如: byte[] mybytarray = Arrays.asList(myintarray).s

为了连接两个库,我需要将包含字节的int[]数组转换为只包含低字节的byte[]数组。(我需要用0xFF屏蔽int,并将它们存储在byte[]数组中。)我只能找到如何在转换int的所有4个字节时执行此操作的示例,我不需要这些示例

作为一个练习,我希望在纯Java8中使用一些简短而高效的代码(即,没有外部库、调用或SOUP的有效Java8代码)。我尝试使用streams,但找不到有效的map();例如:

byte[] mybytarray = Arrays.asList(myintarray).stream().map(v -> v & 0xFF).collect(toList()).toArray(byte[]::new);

但存在错误“无法推断映射(函数)的类型参数”,我不知道如何编写映射。

创建一个与int数组大小相同的字节数组,并让索引计数器从0运行到字节数组的大小-1。在索引计数器处获取int值,计算所需的字节值并将其存储在同一索引计数器中。

不幸的是,STEAM不直接支持
字节类型;即,。没有像
int
long
1那样的
ByteStream
专门化

如果坚持使用流,一个合理有效的解决方案是使用
ByteArrayOutputStream
收集字节:

ByteArrayOutputStream baos(myintarray.length);
Arrays.stream(myintarray).forEachOrdered(i -> baos.write((byte)i));
byte[] byteArray = baos.toArray();
这仅复制阵列一次。for循环和显式数组插入会更好:

byte[] byteArray = new byte[myintarray.length];
for (int i = 0; i < myintarray.length; i++) {
  byteArray[i] = (byte)myintarray[i];
}
这涉及到大量的装箱,最终得到的是更大、更慢的
字节[]
,但是您使用的是纯Java 8解决方案,对吗



1尽管存在组合爆炸参数,但考虑到在许多面向输入/输出的操作中
byte[]
的关键性质,这对我来说似乎总是一个不幸的遗漏。

您不能列出原语。查找数组。流和基元流。@user2357112没有字节流。@ThorbjørnRavnAndersen:是的,所以你需要一个IntStream。这不是疏忽;这是故意的。他们不希望流类和方法组合爆炸来处理不同的原始类型的混合。他们选择的流类型被认为是足够的。当然,我知道他们为什么这么做,而且你不会听到我抱怨缺少
short
char
float
,但是把
byte
留在外面是不幸的。从某种意义上说,它是基本类型,因为如果您选择,您可以将所有其他内容覆盖在
byte
数组上,并且所有基本流类(如
InputStream
)都对字节流进行操作。我经常错过没有字节流操作,因为文件、套接字等都处理字节数组。如果我只能选择两个,我会选择
long
byte
。。。。当然,大多数人最想要的是
int
,所以我知道那是行不通的。组合爆炸这件事真的很遗憾,这是Java处理原语的结果,但如果他们能找到一种更优雅的方法,或者至少为
byte[]
提供包装器,这样他们就可以作为
IntStream
公开,但有高效的底层操作,那就太好了。无论如何,我把我的语言改为“不幸的疏忽”,而不是“严重的疏忽”,这似乎更准确@user2357112@BeeOnRope感谢您提供有关流和字节的好信息!还感谢(对我来说是什么)非常有趣的结尾评论,因为你不知道我工作的实际限制是什么,为谁工作,甚至不知道为什么。:)最后一条评论更像是在暗示“纯Java8”的定义不是很好?这是否意味着只使用Java8中引入的语言特性?当然,
Integer
Byte
类自Java1.x或其他版本以来就已经存在,因此几乎排除了一切。因此,这一限制似乎是不合理和武断的。与许多不断挑战限制的人不同,我不在乎你为谁工作,也不在乎你为什么有这种限制,但限制本身应该明确@用户9999999
Arrays.stream(myintarray).boxed().map(Integer::byteValue)
    .collect(Collectors.toList()).toArray(new Byte[myintarray.length]);