Як перетворити байт [] в байт [] і навпаки?


78

Як перетворити byte[]на, Byte[]а також Byte[]у byte[], у разі використання не будь-якої сторонньої бібліотеки?

Чи є спосіб зробити це швидко, просто використовуючи стандартну бібліотеку?


5
10 питань, ОДИН прийнято? Нічого хорошого
Альфабраво,

Навіщо вам потрібна / є Byte[]? Це не здається хорошою ідеєю ... або використовувати, byte[]або List<Byte>.
Дюни

Може бути корисним, якщо значення можуть бути нульовими, хоча, мабуть, і не дуже ефективними (тобто витрачає будь-яку користь від простору для зберігання байтів через усі посилання на об’єкти)?
DNA

Але ви не можете перетворити a Byte[]на a, byte[]якщо у вас є нульові посилання ...
Дюни

@BalusC гаразд, 1 з 7. Не значно покращився!
Альфабраво,

Відповіді:


54

Byte клас - це обгортка для примітиву byte. Це повинно зробити роботу:

byte[] bytes = new byte[10];
Byte[] byteObjects = new Byte[bytes.length];

int i=0;    
// Associating Byte array values with bytes. (byte[] to Byte[])
for(byte b: bytes)
   byteObjects[i++] = b;  // Autoboxing.

....

int j=0;
// Unboxing Byte values. (Byte[] to byte[])
for(Byte b: byteObjects)
    bytes[j++] = b.byteValue();

4
Напевно рекомендую Byte.valueOf(b)більше new Byte(b). Я був би здивований, якби клас Byte не кешував кожне значення байта.
Дюни

2
Я вважаю, що це може бути краще використовувати Byte.valueOf(byte). JavaDocs заявляє, що цей метод, як правило, слід використовувати переважно перед конструктором Byte(byte), оскільки цей метод, ймовірно, дасть значно кращу продуктивність у просторі та часі, оскільки всі значення байтів кешуються.
Едвін Далорцо,

9
За допомогою автобоксу ви можете просто зробитиbyteObjects[i++] = b;
Code-Apprentice

4
Я б використовував new Byte[bytes.length];замість того, new Byte[10];щоб тримати це розумно.
BalusC,

2
@Juvanis aha, я бачу, що ви використовуєте два "лічильника" у циклі for: один для ітерації над примітивним байтовим масивом та / або масивом байтових об'єктів, а інший для збільшення індексу примітивного байтового масиву та / або байта масив об’єктів. Для мене це погана практика. Якщо цей код підтримується іншими, і хтось змінить лічильник "i" з 0 на інше значення або змінить i ++ на ++ i, індекси більше не збігаються. Я не виступаю за те, щоб спочатку хтось модифікував код, але це нова проблема для початківців. Моя пропозиція підтримує синхронізацію індексів обох масивів.
user504342

62

байт [] до байт []:

byte[] bytes = ...;
Byte[] byteObject = ArrayUtils.toObject(bytes);

Байт [] в байт []:

Byte[] byteObject = new Byte[0];
byte[] bytes = ArrayUtils.toPrimitive(byteObject);

1
Чому це не найкраща відповідь? Будь-яка причина виконання або просто відповіли пізніше?
mvorisek

26
Оскільки ArrayUtils - це не частина Java, а Apache lib.
mvorisek

Я згоден з @mvorisek, це слід вважати найкращою відповіддю. Просто додайте
org.apache.commons.lang3.ArrayUtils

16

Рішення Java 8:

Byte[] toObjects(byte[] bytesPrim) {
    Byte[] bytes = new Byte[bytesPrim.length];
    Arrays.setAll(bytes, n -> bytesPrim[n]);
    return bytes;
}

На жаль, ви не можете зробити це для перетворення з Byte[]на byte[]. Arraysмає setAllдля double[],, int[]і long[], але не для інших примітивних типів.


15

Ви можете використовувати метод toPrimitive у класі бібліотеки Apache Commons ArrayUtils, як запропоновано тут - Java - Byte [] до byte []


Це насправді найкраща відповідь, принаймні для тих, для кого додавання залежності до commons-lang не є проблемою.
ARRG

6
byte[] toPrimitives(Byte[] oBytes)
{

    byte[] bytes = new byte[oBytes.length];
    for(int i = 0; i < oBytes.length; i++){
        bytes[i] = oBytes[i];
    }
    return bytes;

}

Інверсія:

//byte[] to Byte[]
Byte[] toObjects(byte[] bytesPrim) {

    Byte[] bytes = new Byte[bytesPrim.length];
    int i = 0;
    for (byte b : bytesPrim) bytes[i++] = b; //Autoboxing
    return bytes;

}

5

З байта [] в байт []:

    byte[] b = new byte[]{1,2};
    Byte[] B = new Byte[b.length];
    for (int i = 0; i < b.length; i++)
    {
        B[i] = Byte.valueOf(b[i]);
    }

Від байта [] до байта [] (використовуючи наші раніше визначені B):

    byte[] b2 = new byte[B.length];
    for (int i = 0; i < B.length; i++)
    {
        b2[i] = B[i];
    }

2

Якщо хтось віддає перевагу Stream API перед звичайними циклами.

private Byte[] toObjects(byte[] bytes) {
    return IntStream.range(0, bytes.length)
            .mapToObj(i -> bytes[i])
            .toArray(Byte[]::new);
}

1
а навпаки?
ElectRocnic

Я думаю, ви не можете отримати байт [] із потоку. API потоку має mapToInt (), mapToDouble () і mapToLong (), але не mapToByte ().
mkalmo
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.