Easy way to concatenate two byte arrays
Solution 1
Most straightforward:
byte[] c = new byte[a.length + b.length];
System.arraycopy(a, 0, c, 0, a.length);
System.arraycopy(b, 0, c, a.length, b.length);
Solution 2
The most elegant way to do this is with a ByteArrayOutputStream
.
byte a[];
byte b[];
ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );
outputStream.write( a );
outputStream.write( b );
byte c[] = outputStream.toByteArray( );
Solution 3
Here's a nice solution using Guava's com.google.common.primitives.Bytes
:
byte[] c = Bytes.concat(a, b);
The great thing about this method is that it has a varargs signature:
public static byte[] concat(byte[]... arrays)
which means that you can concatenate an arbitrary number of arrays in a single method call.
Solution 4
Another possibility is using java.nio.ByteBuffer
.
Something like
ByteBuffer bb = ByteBuffer.allocate(a.length + b.length + c.length);
bb.put(a);
bb.put(b);
bb.put(c);
byte[] result = bb.array();
// or using method chaining:
byte[] result = ByteBuffer
.allocate(a.length + b.length + c.length)
.put(a).put(b).put(c)
.array();
Note that the array must be appropriately sized to start with, so the allocation line is required (as array()
simply returns the backing array, without taking the offset, position or limit into account).
Solution 5
Another way is to use a utility function (you could make this a static method of a generic utility class if you like):
byte[] concat(byte[]...arrays)
{
// Determine the length of the result array
int totalLength = 0;
for (int i = 0; i < arrays.length; i++)
{
totalLength += arrays[i].length;
}
// create the result array
byte[] result = new byte[totalLength];
// copy the source arrays into the result array
int currentIndex = 0;
for (int i = 0; i < arrays.length; i++)
{
System.arraycopy(arrays[i], 0, result, currentIndex, arrays[i].length);
currentIndex += arrays[i].length;
}
return result;
}
Invoke like so:
byte[] a;
byte[] b;
byte[] result = concat(a, b);
It will also work for concatenating 3, 4, 5 arrays, etc.
Doing it this way gives you the advantage of fast arraycopy code which is also very easy to read and maintain.
Related videos on Youtube
androidGuy
Updated on August 09, 2021Comments
-
androidGuy over 2 years
What is the easy way to concatenate two
byte
arrays?Say,
byte a[]; byte b[];
How do I concatenate two
byte
arrays and store it in anotherbyte
array?-
Maarten Bodewes over 5 yearsNote please that Apache Commons, Google's Guava,
System.arrayCopy
,ByteBuffer
and the - not so efficient but readable -ByteArrayOutputStream
have all been covered. We've got more than 7 dupes of the answers given here. Please don't post any more dupes.
-
-
Wayne Uroda over 11 years@vipw The reason why this is elegant is because if/when you wish to concatenate a third array later, you simply add the line
outputStream.write( c );
- you don't have to go back and edit the line where you create the result byte array. Also, re-ordering the arrays is simple, unlike using the arraycopy method. -
gardarh about 11 yearsAdditionally this is far easier when working with more than just 2 byte arrays.
-
vikingsteve over 10 yearsWhether it's wasting cpu and memory depends on how often you do the operation. If it's a billion times a second - sure, optimize it. Otherwise, readability and maintainability might be the winning considerations.
-
kalefranz over 10 years@click_whir Sorry man, but ReadTheDocs.
ByteBuffer.allocate(int)
is a static method that returns an instantiatedjava.nio.HeapByteBuffer
, a subclass ofByteBuffer
. The.put()
and.compact()
methods--and any other abstract-ness--is taken care of. -
Maarten Bodewes almost 10 yearsIf memory consumption and/or performance is a concern, be sure to use
a.length + b.length
as argument for theByteArrayOutputStream
constructor. Note that this method still will copy all bytes to a new array to assign toc[]
! Consider theByteBuffer
method a close contender, that does not waste memory. -
Maarten Bodewes over 9 years@kalefranz Removed
compact()
line as it is incorrect. -
DarqueSandu almost 9 yearsTake care in using the ByteBuffer's array() method - unless you absolutely know what you are doing and maintainability is not an issue, there are no guarantees that the zeroeth position in the bytebuffer always corresponds to index 0 of the byte array. See here. I solve this by issuing
bb.flip(); bb.get(result);
in stead of thebyte[] result = bb.array();
line. -
searchengine27 almost 9 yearsI can't really give this a thumbs up because this is just a code snippet. There is no explanation of the underlying pieces here, which is the part I care about (and I think most people would). I would gladly give this a thumbs up if there was a performance comparison between System#arrayCopy(Object, int, Object, int, int) and ByteArrayOutputStream#put(byte[]), and detailed which scenario is best for both options. Also, that being said, the answer should also include arrayCopy since that is another solution.
-
Carlos Andrés García almost 8 yearsI tried
ArrayUtils.addAll(a, b)
andbyte[] c = Bytes.concat(a, b)
, but the latter is faster. -
Tomasz Przybylski almost 8 yearsMaybe. I don't know Guava library so if it is, it's better to use it. Did you check it for very large arrays?
-
Carlos Andrés García almost 8 yearsWhen I did the test, The Firts array was 68 elements length y the second 8790688 length.
-
amos almost 7 yearsa bit off topic to this question, but is exactly what I was looking for.
-
Maarten Bodewes over 5 yearsSame answer as the accepted one and sorry, 5 minutes late.
-
Maarten Bodewes over 5 yearsSame answer as this one but more than 1 year late. Uses method chaining, but that would be better put into the existing answer.
-
Maarten Bodewes over 5 yearsThis wastes memory. The method would be OK for two smaller arrays, but it certainly will tax the garbage collector for more arrays.
-
Maarten Bodewes over 5 yearsNo, that's Wayne's way to do it, you're 5 years late.
-
John McClane over 5 years@MaartenBodewes If you are not sure about "l1" (which is just an alias for ISO 8859-1), don't use the word "certainly". Which particular byte value will be wiped out? As for the memory usage, the question was about the easy way to concatenate two byte arrays, not about most memory efficient one.
-
Daniel De León over 5 years@MaartenBodewes Thanks to you, I use your comment to exercise coding today, now is more different and with better performance.
-
Maarten Bodewes over 5 yearsI'm not sure it will matter too much, seeing that array sizes do not change in the runtime either, but it is now different at least from the other solution.
-
Maarten Bodewes over 5 yearsI've put down some warnings and did some testing. For Latin 1 and the Oracle provided runtime (11) this does seem to work. So I provided extra info and removed my comment and downvote. I hope that's OK for you, otherwise please roll back.
-
Maarten Bodewes over 5 years@DarqueSandu Although that's good advice in general, careful reading of the
allocate
method reveals the following: " The new buffer's position will be zero, its limit will be its capacity, its mark will be undefined, and each of its elements will be initialized to zero. It will have a backing array, and its array offset will be zero." So for this particular piece of code, where theByteBuffer
is allocated internally, it's not an issue. -
lepe over 3 yearsThis is the simplest way. BTW, no difference if you are using Groovy.
-
Shuhad zaman about 2 yearsworked like charm