0

I want to do a method to convert binary String to byte array and I wanted to use Java 8 Stream API but I cannot use map to get a byte array. So I have done like this. Do you know any better way to do it?

private static byte[] getBytes(String bitString)
{
    int [] range = IntStream.range(0,  bitString.length() / 8).toArray();
    byte[] byteArray = new byte[range.length];
    for (int i = 0; i < range.length; i++) {
        int pos = range[i];
        byteArray[i] = Byte.parseByte(StringUtils.netSubstring(bitString, pos * 8, 8), 2);
    }
    return  byteArray;
}
2
  • 1
    What does StringUtils.netSubstring do? Commented Sep 1, 2020 at 15:18
  • Sorry for the confussion. It is a method to do the substring as .Net C# does because I'm translating a lot fo code written in .Net Commented Sep 2, 2020 at 19:14

1 Answer 1

1

First, it’s important to know that Byte.parseByte(…, 2) expects an optional + or - sign, followed by a positive magnitude. So, if the string has no sign, eight digits, and the leftmost is a one, it will throw an exception, because that positive number wouldn’t fit into the signed byte type. You have to use Integer.parseInt(…,2) instead and cast the result to a byte.

Further, it’s a bit strange to create that int[] range array containing strictly ascending numbers. Within the subsequent loop, pos and i will always have the same value. So the array is entirely obsolete.

Considering these two points, you get the simplified

private static byte[] getBytes(String bitString) {
    byte[] byteArray = new byte[bitString.length()/8];
    for(int i = 0; i < byteArray.length; i++) {
        byteArray[i] = (byte)Integer.parseInt(bitString.substring(i * 8, i * 8 + 8), 2);
    }
    return  byteArray;
}

There is no byte variant of Stream, so the only way to express this via the Stream API would be

private static byte[] getBytes2(String bitString) {
    byte[] byteArray = new byte[bitString.length()/8];
    IntStream.range(0, byteArray.length)
        .forEach(i -> byteArray[i] = (byte)Integer.parseInt(
                                         bitString.substring(i * 8, i * 8 + 8), 2));
    return byteArray;
}

which has no real benefit.

But the whole operation can be seen as an academic exercise anyway, as we can simply use

byte[] ba = new BigInteger(bitString, 2).toByteArray();

This creates an additional first zero byte, if the value would otherwise be negative. If that’s a problem, you can remove it afterwards like

if(ba[0] == 0 && bitString.charAt(0) == '1') ba = Arrays.copyOfRange(ba, 1, ba.length);

and it’s still simpler than doing it manually.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.