我有以下二维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>
答案 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();
}
}