daniboy000
daniboy000

Reputation: 1129

ArrayList of byte[] to byte[] using stream in Java

I have an ArrayList of byte[] and I'm wondering if it's possible to convert this to a byte[] using stream from Java 8. All the arrays inside the ArrayList have the same size.

ArrayList<byte[]> buffer = new ArrayList();

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

Upvotes: 6

Views: 14668

Answers (4)

user4910279
user4910279

Reputation:

Try this.

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

Upvotes: 16

meowmeowxw
meowmeowxw

Reputation: 81

This is a possible solution with the Guava library:

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()));

Upvotes: 3

Nir Alfasi
Nir Alfasi

Reputation: 53525

You can use Guava library, it has Bytes which supports converting byte[] to List<Byte> and back via:

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

and

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

Another option is to simply iterate and copy the arrays, one by one, to one big byte[], it seems to me simpler and more straightforward that the code in the accepted answer...

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;
}

Upvotes: 2

G&#225;bor Bakos
G&#225;bor Bakos

Reputation: 9100

flatMap should be what you are looking for, ideally it should look like this:

byte[] output = buffer.stream().flatMap(x -> Arrays.stream(x)).toArray(n -> new byte[n])

But it does not compile.

With some helper methods:

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;
}

The following should work (but not very nice or efficient):

byte[] output = unBox(buffer.stream().flatMap(x -> Arrays.stream(box(x))).toArray(n -> new Byte[n]));

Upvotes: 2

Related Questions