How to convert byte[] to Byte[] and the other way around?
Asked Answered
V

9

98

How to convert byte[] to Byte[] and also Byte[] to byte[], in the case of not using any 3rd party library?

Is there a way to do it fast just using the standard library?

Vengeful answered 17/10, 2012 at 22:27 Comment(6)
10 questions, ONE accepted? No goodDinadinah
Why do you need/have a Byte[]? Doesn't seem like a good idea... either use byte[] or List<Byte>.Galilean
Might be useful if the values can be null, though probably not very efficient (ie. wastes any space-benefit of storing bytes, because of all the object references)?Convulsion
But you can't convert a Byte[] to a byte[] if you have null references...Galilean
@BalusC ok, 1 of 7. Haven't improved a lot!Dinadinah
@Galilean One reason to have Byte[] is that it becomes an intermediate form of trying to call toArray on a List<Byte>. In this case, writing your own loop seems to be the easiest way.Hedelman
T
62

Byte class is a wrapper for the primitive byte. This should do the work:

byte[] bytes = new byte[10];
Byte[] byteObjects = new Byte[bytes.length];

int i=0;    
// Associating Byte array values with bytes. (byte[] to Byte[])
for(byte b: bytes)
   byteObjects[i++] = b;  // Autoboxing.

....

int j=0;
// Unboxing Byte values. (Byte[] to byte[])
for(Byte b: byteObjects)
    bytes[j++] = b.byteValue();
Trooper answered 17/10, 2012 at 22:31 Comment(7)
Would definitely recommend Byte.valueOf(b) over new Byte(b). I would be surprised if the Byte class didn't cache every single value for a byte.Galilean
I believe that it might be better to use Byte.valueOf(byte). JavaDocs say that this method should generally be used in preference to the constructor Byte(byte), as this method is likely to yield significantly better space and time performance since all byte values are cached.Badge
With autoboxing, you can simply do byteObjects[i++] = b;Ola
I'd use new Byte[bytes.length]; instead of new Byte[10]; to keep it sensible.Anglia
This answer isn't correct. The i++ and j++ in the for-each loop don't do anything useful. You need to use the basic for-loop: for (int i=0; i<bytes.length;i++) { byteObjects[i] = b[i]; }. Same goes for unboxing.Alice
@Alice have you ever debugged my code? with my code i and j goes from 0 to 10 and handles the job.Trooper
@Trooper aha, I see that you use two "counters" in the for-loop: one to iterate over the primitive byte array and/or Byte object array, and another one for incrementing the index of the primitive byte array and/or Byte object array. To me, this is bad practice. If this code is maintained by others, and someone would modify the counter "i" from 0 to another value, or would change the i++ into ++i, the indexes no longer match. I am not advocating anyone should modify the code in the first place, but it's a common pitfall for beginners. My suggestion keeps the indexes of both arrays in sync.Alice
T
91

byte[] to Byte[] :

byte[] bytes = ...;
Byte[] byteObject = ArrayUtils.toObject(bytes);

Byte[] to byte[] :

Byte[] byteObject = new Byte[0];
byte[] bytes = ArrayUtils.toPrimitive(byteObject);

Note: ArrayUtils are not a part of Java, but Apache lib

Thordis answered 5/9, 2016 at 11:38 Comment(7)
Why this is not the best answer? Any performace reason or just answered later?Tuberous
Because the ArrayUtils are not a part of Java, but Apache lib.Tuberous
I agree with @mvorisek, this should be considered the best answer. Just add org.apache.commons.lang3.ArrayUtilsRhythmist
Unfortunately, ArrayUtils is not part of standard Java packages.Grogshop
apache commons lang is a great package that should be part of any java project.Nedanedda
The question explicitly asks for a non third party library.Kristofor
Not using 3rd party libraries, when they're widely available, efficient, stable and maintained, is bad practice, don't reinvent the wheel.Jerz
T
62

Byte class is a wrapper for the primitive byte. This should do the work:

byte[] bytes = new byte[10];
Byte[] byteObjects = new Byte[bytes.length];

int i=0;    
// Associating Byte array values with bytes. (byte[] to Byte[])
for(byte b: bytes)
   byteObjects[i++] = b;  // Autoboxing.

....

int j=0;
// Unboxing Byte values. (Byte[] to byte[])
for(Byte b: byteObjects)
    bytes[j++] = b.byteValue();
Trooper answered 17/10, 2012 at 22:31 Comment(7)
Would definitely recommend Byte.valueOf(b) over new Byte(b). I would be surprised if the Byte class didn't cache every single value for a byte.Galilean
I believe that it might be better to use Byte.valueOf(byte). JavaDocs say that this method should generally be used in preference to the constructor Byte(byte), as this method is likely to yield significantly better space and time performance since all byte values are cached.Badge
With autoboxing, you can simply do byteObjects[i++] = b;Ola
I'd use new Byte[bytes.length]; instead of new Byte[10]; to keep it sensible.Anglia
This answer isn't correct. The i++ and j++ in the for-each loop don't do anything useful. You need to use the basic for-loop: for (int i=0; i<bytes.length;i++) { byteObjects[i] = b[i]; }. Same goes for unboxing.Alice
@Alice have you ever debugged my code? with my code i and j goes from 0 to 10 and handles the job.Trooper
@Trooper aha, I see that you use two "counters" in the for-loop: one to iterate over the primitive byte array and/or Byte object array, and another one for incrementing the index of the primitive byte array and/or Byte object array. To me, this is bad practice. If this code is maintained by others, and someone would modify the counter "i" from 0 to another value, or would change the i++ into ++i, the indexes no longer match. I am not advocating anyone should modify the code in the first place, but it's a common pitfall for beginners. My suggestion keeps the indexes of both arrays in sync.Alice
D
22

Java 8 solution:

Byte[] toObjects(byte[] bytesPrim) {
    Byte[] bytes = new Byte[bytesPrim.length];
    Arrays.setAll(bytes, n -> bytesPrim[n]);
    return bytes;
}

Unfortunately, you can't do this to convert from Byte[] to byte[]. Arrays has setAll for double[], int[], and long[], but not for other primitive types.

Drachma answered 16/6, 2014 at 22:50 Comment(1)
Best answer for me. Simple code and no third-party library.Athematic
C
16

You could use the toPrimitive method in the Apache Commons lang library ArrayUtils class, As suggested here - Java - Byte[] to byte[]

Conditioner answered 12/11, 2013 at 9:56 Comment(1)
This is actually the best answer, at least for anyone for whom adding a dependency to commons-lang isn't an issue.Foltz
O
8
byte[] toPrimitives(Byte[] oBytes)
{

    byte[] bytes = new byte[oBytes.length];
    for(int i = 0; i < oBytes.length; i++){
        bytes[i] = oBytes[i];
    }
    return bytes;

}

Inverse:

//byte[] to Byte[]
Byte[] toObjects(byte[] bytesPrim) {

    Byte[] bytes = new Byte[bytesPrim.length];
    int i = 0;
    for (byte b : bytesPrim) bytes[i++] = b; //Autoboxing
    return bytes;

}
Onassis answered 16/6, 2014 at 22:43 Comment(0)
C
5

From byte[] to Byte[]:

    byte[] b = new byte[]{1,2};
    Byte[] B = new Byte[b.length];
    for (int i = 0; i < b.length; i++)
    {
        B[i] = Byte.valueOf(b[i]);
    }

From Byte[] to byte[] (using our previously-defined B):

    byte[] b2 = new byte[B.length];
    for (int i = 0; i < B.length; i++)
    {
        b2[i] = B[i];
    }
Convulsion answered 17/10, 2012 at 22:34 Comment(0)
P
4

If someone preferes Stream API over ordinary loops.

private Byte[] toObjects(byte[] bytes) {
    return IntStream.range(0, bytes.length)
            .mapToObj(i -> bytes[i])
            .toArray(Byte[]::new);
}
Perfectionist answered 8/4, 2020 at 11:15 Comment(2)
and the other way round?Porshaport
I think you can't get byte[] from Stream. Stream api has mapToInt(), mapToDouble() and mapToLong() methods but not mapToByte().Perfectionist
P
0

Step back. Look at the bigger picture. You're stuck converting byte[] to Byte[] or vice versa because of Java's strict type casing with something like this

List< Byte> or List<Byte[]>

Now you have byte[] and Byte[] and have to convert. This will help.

Keep all your byte[]s in a list like this: List<byte[]> instead of List< Byte> or List<Byte[]>. (byte is a primitive, byte[] is an object)

As you acquire bytes do this (networking socket example):

ArrayList<byte[]> compiledMessage = new ArrayList<byte[]>;
...
compiledMessage.add(packet.getData());

Then, when you want to put all your bytes in a single message, do this:

byte[] fromListOfNotByteArray (List<byte[]> list) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos;
    try {
        oos = new ObjectOutputStream(baos);
        oos.writeObject(list);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return baos.toByteArray();
}

That way, you can keep all your parts in List<byte[]> and your whole in byte[] without a bunch of crazy copy tasks in for loops with little baby byte[]s everywhere. ;)

Now you know -- teach others.

Pelotas answered 21/2, 2022 at 20:14 Comment(0)
C
0

Since Java 8:

byte[] bytes = new bytes[byteObject.length];
IntStream.range(0, byteObject.length).forEach(x -> bytes [x] = byteObject[x]);
Ceremonial answered 5/2, 2023 at 17:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.