Java: самый быстрый способ преобразования байта массива bye [1000] в массив int [500] - PullRequest
2 голосов
/ 19 января 2012

Цель состоит в том, чтобы преобразовать каждую пару байтов в один беззнаковый 16-битный тип int. В C я определил бы массив [500] из 16-битного неиспользуемого указателя int и указал бы на него массив байтов, но в Java я не знаю о таком сокращении. Я знаю, что в Java нет 16-битного типа данных, кроме char, однако это не проблема. Нам нужно только скопировать каждые два последовательных двух байта в одно целое массива целых чисел. Таким образом, массив целых чисел содержит значения int в диапазоне от 0 до 65535 (2 ^ 16-1).

Ответы [ 3 ]

4 голосов
/ 19 января 2012

Вы можете использовать ByteBuffer, чтобы избавиться от смещения и маскировки, что вы часто ошибаетесь.(и есть подписанные и неподписанные тоже)

ByteBuffer bb = ByteBuffer.wrap(bytes);
bb.order(ByteOrder.BIG_ENDIAN);  // or LITTLE_ENDIAN
short[] shorts = new short[bytes.length/2];
for (int i=0; i<shorts.length; i++)
   shorts[i] = bb.getShort();

Примечание - если вы действительно хотите "короткую без знака", в java такого нет, поэтому ваш массив должен быть целым числом.Вы конвертируете, используя

for (int i=0; i<intArray.length; i++) {
   short s = bb.getShort();
   intArray[i] = s & 0xFFFF; // mask off all the high order bits
}
2 голосов
/ 19 января 2012

Я думаю, что в Java нет хороших трюков, таких как псевдонимы, которые вы можете сделать в C. Вам придется делать это вручную:

public int[] pack(byte[] bytes) {
    int n = bytes.length >> 1;
    int[] packed = new int[n];
    for (int i = 0; i < n; ++i) {
        int i2 = i << 1;
        int b1 = bytes[i2] & 0xff;
        int b2 = bytes[i2 + 1] & 0xff;
        packed[i] = (b1 << 8) | b2;
    }
    return packed;
}

(Вероятно, это может быть немного ускорено, но, вероятно, не стоит этого для 1000 элементов, если это не сделано много.) Обратите внимание, что повышение с byte до int требует немного дополнительной работы, чтобы справиться расширение нежелательного знака.

1 голос
/ 19 января 2012

На самом деле в Java нет 16-разрядного целочисленного типа без знака - за исключением , может быть, char, если вы чувствуете оскорбление языка. Тем не менее, это прекрасное время для использования популярной утилиты Guava :

public short[] pack(byte[] bytes) {
   short[] result = new short[bytes.length / 2];
   for (int i = 0; i < bytes.length; i += 2) {
     result[i/2] = Shorts.fromBytes(bytes[i], bytes[i+1]);
   }
}

И если вы действительно требовательны к производительности, вы можете добавить отдельный счетчик или использовать сдвиг вправо вместо деления, но это достаточно просто.

...