преобразование int [] в byte [] без создания новых объектов - PullRequest
2 голосов
/ 24 августа 2009

У меня есть int [] в Java, который я хочу преобразовать в байт [].

Теперь обычный способ сделать это - создать новый байт [], в 4 раза превышающий размер массива int, и скопировать все байты байтов в новый байтовый массив.

Однако единственная причина сделать это из-за правил безопасности типов Java. Массив int уже является байтовым массивом. Просто java не позволяет приводить int [] к байту [], а затем использовать его как байт [].

Есть ли способ, возможно, с помощью jni, сделать массив int похожим на байтовый массив для java?

Ответы [ 3 ]

9 голосов
/ 24 августа 2009

Нет. Нет возможности реализовать объект с собственным интерфейсом массива Java.

Мне кажется, что вы хотите, чтобы объект обернул ваш int [], и представил методы для доступа к нему в байтовом массиве. например,

public class ByteArrayWrapper {
   private int[] array;

   public int getLength() {
      return array.length * 4;
   }

   public byte get(final int index) {
      // index into the array here, find the int, and then the appropriate byte
      // via mod/div/shift type operations....
     int val = array[index / 4];
     return (byte)(val >> (8 * (index % 4)));
   }
}

(вышеупомянутое не тестируется / не компилируется и т. Д. И зависит от ваших требований к порядку байтов. Это чисто иллюстративно )

4 голосов
/ 25 августа 2009

В зависимости от ваших точных требований, вы можете использовать класс NIO java.nio.ByteBuffer. Сделайте свое первоначальное распределение как ByteBuffer, и используйте его getInt и putInt методы для доступа к значениям int. Когда вам нужно получить доступ к буферу в виде байтов, вы можете использовать методы get и put. ByteBuffer также имеет метод asIntBuffer, который изменяет поведение get и put по умолчанию на int вместо байта.

Если вы используете JNI, непосредственно выделенный ByteBuffer (в некоторых случаях) разрешает прямой доступ к указателю в вашем коде C.

http://java.sun.com/javase/6/docs/api/java/nio/ByteBuffer.html

Например,

import java.nio.ByteBuffer;
import java.nio.IntBuffer;

// …

int[] intArray = { 1, 2, 3, 4 };

ByteBuffer byteBuffer = ByteBuffer.allocate(data.length * 4);        
IntBuffer intBuffer = byteBuffer.asIntBuffer();
intBuffer.put(intArray);

byte[] byteArray = byteBuffer.array();
1 голос
/ 24 августа 2009

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

Мне также очень любопытно, как выглядит существующий код и какую дополнительную скорость вы ожидаете.

Вы знаете правила оптимизации, верно?

  • 1) Не оптимизировать.
  • 2) Если вы эксперт, см. Правило 1.
  • 3) если вы являетесь экспертом, написали максимально четкий код и у вас есть временные тесты, которые не пройдены, тогда:
  • 3a) написать оптимизированную версию и оставить неоптимизированный код в качестве комментариев
  • 3b) повторите тестирование, если ваш оптимизированный код не прошел тестов скорости, вернитесь!
  • 3c) объясните, почему вы так закодировали в комментариях. Включите ваши измерения скорости и ссылки на требования.
  • 3d) если правило 3 кажется слишком трудоемким, см. Правило 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...