【问题标题】:Convert an int array to a byte array while maintaining the size将 int 数组转换为 byte 数组,同时保持大小
【发布时间】:2016-05-22 14:47:57
【问题描述】:

我有以下二维int数组:

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

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

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

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

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

【问题讨论】:

  • 至于您的示例解决方案:512 = 128 * 4 和 int 是 4 个字节长。该解决方案只是从int 中获取所有字节。你想要另一种转变,所以你必须使用另一种方法。
  • 你能保证你的第一个数组总是8的倍数吗?
  • @Paul 既然你提到了它就说得通了。
  • @AndrewWilliamson 确实是一个重要的问题。 是的,我可以保证。大小总是能被 8 整除。
  • 所以结果应该是byte b[][] = new byte[128][16],对吧? (而不是byte b[] = new byte[128*16] ...)

标签: java arrays multidimensional-array bytearray


【解决方案1】:

既然您知道数组总是 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));

【讨论】:

    【解决方案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 的算法。

    【讨论】:

    • 啊,是的,我什至没有考虑位排序。
    【解决方案3】:

    您链接到的方法通过简单地考虑 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();
        }
    
    
    }
    

    【讨论】:

      猜你喜欢
      • 2014-03-05
      • 2022-01-11
      • 2018-08-31
      • 2021-05-14
      • 1970-01-01
      • 2016-12-31
      • 1970-01-01
      • 2014-07-02
      • 1970-01-01
      相关资源
      最近更新 更多