Java中使用流将byte[]的ArrayList转换为byte[]

6
我有一个byte[]的ArrayList,我想知道是否可以使用Java 8的流将其转换为byte[]。ArrayList中的所有数组大小都相同。
ArrayList<byte[]> buffer = new ArrayList();

byte[] output = buffer.stream(...)

将所有的byte[]连接起来吗? - azro
是的,我想要将ArrayList中的所有字节合并成一个唯一的字节数组。 - daniboy000
4个回答

15

试试这个。

List<byte[]> list = Arrays.asList("abc".getBytes(), "def".getBytes());
byte[] result = list.stream()
    .collect(
        () -> new ByteArrayOutputStream(),
        (b, e) -> b.write(e, 0, e.length),
        (a, b) -> {}).toByteArray();
System.out.println(new String(result));
// -> abcdef

这只适用于API级别24及以上吗? - Umair M
1
@UmairM 我不知道"API level 24"是什么意思。但它需要Java 8或更高版本。 - user4910279
2
为什么组合器是无操作的?b.writeTo(a);就足够了。 - user167019
3
当你使用b.write(e, 0, e.length)时,你不需要处理IOException异常,因此整个lambda表达式简化为(b, e) -> b.write(e, 0, e.length)。此外,我赞同@user167019的观点,不要编写有问题的combiner函数,尤其是当有简单直接的实现方法时,例如b.writeTo(a) - Holger

3

以下是使用Guava库的可能解决方案:

List<byte[]> list = Arrays.asList("abc".getBytes(), "def".getBytes());
byte[] res = Bytes.toArray(list.stream()
        .map(byteArray -> Bytes.asList(byteArray))
        .flatMap(listArray -> listArray.stream())
        .collect(Collectors.toList()));

2
flatMap 应该是您正在寻找的,理想情况下应该如下所示:
byte[] output = buffer.stream().flatMap(x -> Arrays.stream(x)).toArray(n -> new byte[n])

但是它无法编译。

使用一些辅助方法:

private Byte[] box(final byte[] arr) {
    final Byte[] res = new Byte[arr.length];
    for (int i = 0; i < arr.length; i++) {
        res[i] = arr[i];
    }
    return res;
}
private byte[] unBox(final Byte[] arr) {
    final byte[] res = new byte[arr.length];
    for (int i = 0; i < arr.length; i++) {
        res[i] = arr[i];
    }
    return res;
}

以下内容应该可以实现(不太好看,也不是很高效):
byte[] output = unBox(buffer.stream().flatMap(x -> Arrays.stream(box(x))).toArray(n -> new Byte[n]));

1
无法编译。 - Jorn Vernee
toArray 不能用于输出原始数组(泛型不允许它)。这仍然无法编译。 - 4castle
已更新为可编译版本。(虽然我承认它不是很好看。) - Gábor Bakos

2
您可以使用Guava库,它具有支持通过以下方式将byte[]转换为List<Byte>和反向转换的Bytes

public static List<Byte> asList(byte... backingArray)

并且

public static byte[] toArray(Collection<? extends Number> collection)

另一种选择是简单地迭代并逐个复制数组到一个大的byte[]中,这对我来说比接受答案中的代码更简单和直接...
public static void main(String[] args) {
    List<byte[]> list = Arrays.asList("abc".getBytes(), "def".getBytes());
    byte[] flattened= flatByteList(list);
    System.out.println(new String(flattened)); // abcdef
}

private static byte[] flatByteList(List<byte[]> list) {
    int byteArrlength = list.get(0).length;
    byte[] result = new byte[list.size() * byteArrlength]; // since all the arrays have the same size
    for (int i = 0; i < list.size(); i++) {
        byte[] arr = list.get(i);
        for (int j = 0; j < byteArrlength; j++) {
            result[i * byteArrlength + j] = arr[j];
        }
    }
    return result;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接