将int数组转换为字节数组,同时保持大小

时间:2016-02-11 17:18:58

标签: java arrays multidimensional-array bytearray

我有以下二维int数组:

int[][] array = new int[128][128];

此二维数组仅包含 1 。我想读取每一行并从其内容中生成byte[](字节数组)。例如,假设第一行是:0101111000111...101,由128个数字组成。我希望这一行是128位的byte[](这意味着16个字节)。

将每行转换为字节数组的效率最多的方法是什么? 请记住,保持大小重要 。由于每行由128“位”组成,因此字节数组的大小应为16字节(128/8)。

我考虑过如何做到这一点的一种方法是将每一行变成BigInteger,然后将其转换为字节数组,但不幸的是我无法产生正确的结果。我也尝试过StackOverflow可用的其他一些选项无济于事。例如this解决方案产生512的输出,我不明白为什么。

由于上述原因,我不认为这篇文章是重复的,因为各种问题和答案都没有考虑到字节数组的大小及其与int数组的相关性。 < / p>

3 个答案:

答案 0 :(得分:2)

由于您知道数组将始终是8的倍数,因此您可以通过位操作安全地从二进制转换为字节。

public byte getByte(int[][] array, int x, int y) {
    byte result = 0;
    for (int bit = 0; bit < 8; bit++)
        result += (byte)(array[x][y + bit] * (1 << bit));
    return result;
}

或者,正如@Andreas所指出的,最重要的位通常是第一位的。只需将for循环更改为:

result += (byte)(array[x][y + bit] * (128 >> bit));

答案 1 :(得分:2)

这是一维数组的代码。您只需对2D数组的外部数组重复执行此操作。

int[] bits = {0,1,0,1,1,1,1,0,0,0,1,1,1,1,0,1};
assert bits.length % 8 == 0;

byte[] bytes = new byte[bits.length / 8];
for (int i = 0; i < bytes.length; i++) {
    int b = 0;
    for (int j = 0; j < 8; j++)
        b = (b << 1) + bits[i * 8 + j];
    bytes[i] = (byte)b;
}

for (int i = 0; i < bytes.length; i++)
    System.out.printf("%02x ", bytes[i]); // prints: 5e 3d 
System.out.println();

这是更常见的Most Significant Bit First @AndrewWilliamson的回答显示了Least Significant Bit First的算法。

答案 2 :(得分:1)

您链接的方法通过简单地考虑int包含的四个单独字节将int转换为字节。

您需要的是一种在结果字节中设置各个位的方法。这可以通过检查输入数组中的128个值中的每一个是0还是1来完成,并相应地设置输出数组中的相应位。这可以独立完成每一行。

这是一个MCVE,显示转换过程并打印并比较结果:

import java.util.Random;

public class IntArrayToByteArray2D
{
    public static void main(String[] args)
    {
        int sizeX = 128;
        int sizeY = 128;
        int input[][] = new int[sizeX][sizeY];

        Random random = new Random(0);
        for (int x=0; x<sizeX; x++)
        {
            for (int y=0; y<sizeY; y++)
            {
                boolean b = random.nextBoolean();
                input[x][y] = b ? 1 : 0;
            }
        }

        System.out.println("Input: ");
        String inputString = createString(input);
        System.out.println(inputString);

        byte output[][] = convert(input);
        String outputString = createString(output);
        System.out.println(outputString);

        System.out.println(inputString.equals(outputString));
    }

    private static byte[][] convert(int input[][])
    {
        byte output[][] = new byte[input.length][];
        for (int i=0; i<input.length; i++)
        {
            output[i] = convert(input[i]);
        }
        return output;
    }

    private static byte[] convert(int input[])
    {
        // Check whether input.length is divisible by 8, if desired
        byte output[] = new byte[input.length >> 3];
        for (int i=0; i<output.length; i++)
        {
            for (int j=0; j<8; j++)
            {
                if (input[(i<<3)+j] != 0)
                {
                    output[i] |= (1 << j); 
                }
            }
        }
        return output;
    }

    private static String createString(int array[][])
    {
        StringBuilder sb = new StringBuilder();
        for (int x=0; x<array.length; x++)
        {
            for (int y=0; y<array[x].length; y++)
            {
                sb.append(array[x][y]);
            }
            sb.append("\n");
        }
        return sb.toString();
    }

    private static String createString(byte array[][])
    {
        StringBuilder sb = new StringBuilder();
        for (int x=0; x<array.length; x++)
        {
            for (int y=0; y<array[x].length; y++)
            {
                for (int b=0; b<8; b++)
                {
                    if ((array[x][y] & (1<<b)) == 0)
                    {
                        sb.append("0");
                    }
                    else
                    {
                        sb.append("1");
                    }
                }
            }
            sb.append("\n");
        }
        return sb.toString();
    }


}