【问题标题】:java 8: how to stream an array of int, extract low bytes, and create an array of bytejava 8:如何流式传输 int 数组、提取低字节并创建字节数组
【发布时间】:2017-03-17 21:58:59
【问题描述】:

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

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

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

但出现错误“无法推断 map(Function) 的类型参数”,我不明白如何编写地图。

【问题讨论】:

  • 你不能创建一个基元列表。查找 Arrays.stream 和原始流。
  • @user2357112 没有字节流。
  • @ThorbjørnRavnAndersen:是的,所以你需要一个 IntStream。

标签: java java-stream


【解决方案1】:

很遗憾,steam 不直接支持byte 类型; IE,。没有像 intlong1 那样的 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 一样快。

如果您真的坚持使用 Streams 的 1-liner,您可以获得 Byte[] 而不是 byte[],如下所示:

Arrays.stream(myintarray).boxed().map(Integer::byteValue)
    .collect(Collectors.toList()).toArray(new Byte[myintarray.length]);

这涉及大量的拳击,你最终会得到一个更大更慢的Byte[],但是你使用了一个纯Java 8解决方案,对吧?


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

【讨论】:

  • 这不是疏忽;这是故意的。他们不希望流类和方法的组合爆炸来处理原始类型的不同混合。他们选择的流类型被认为是足够的。
  • 当然,我知道为什么他们这样做了,你不会听到我抱怨缺少shortcharfloat,但离开@987654337 @在寒冷中很不幸。在某种程度上,它是 the 原始类型,因为您可以选择将其他所有内容覆盖在 byte 数组上,并且所有基本流类(如 InputStream)都对字节流进行操作。我经常错过没有字节流操作,因为文件、套接字等都处理字节数组。如果我只能选择两个,我会选择longbyte
  • ...当然,大多数人最想要的是int,所以我知道那是行不通的。组合爆炸的事情真的很可惜,这是 Java 如何处理原语的结果,但如果他们找到一种更优雅的方法来解决它,或者至少为byte[] 提供包装器,这样它们就可以暴露为IntStream 但有高效的底层操作。无论如何,我将我的语言调整为“不幸的遗漏”,而不是“严重疏忽”,这似乎更准确。 @user2357112
  • @BeeOnRope 感谢您提供有关流和字节的良好信息!还要感谢(对我来说是什么)非常有趣的结束 cmets,因为您不知道我正在工作的实际限制,为谁,甚至为什么。 :)
  • 嗯,最后一条评论更多地表明“纯 Java 8”的定义不是很明确?这是否意味着只使用 Java 8 中引入的语言特性?当然,IntegerByte 类自 Java 1.x 或其他任何东西以来就已经存在,因此几乎排除了一切。因此,限制似乎是不正确的和任意的。与许多不断挑战限制的人不同,我不太关心为谁工作或为什么你有这个限制,但限制本身应该明确。 @user9999999
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2011-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-28
    相关资源
    最近更新 更多