1. Overview
1.概述
While Byte is a wrapper of the primitive byte, and the conversion can be done automatically by autoboxing for individual values, it’s important to note that this automatic conversion doesn’t extend to arrays. In this article, we’ll dive into the different approaches to converting byte arrays to Byte arrays and vice versa in Java.
虽然 Byte 是 包的 原型 byte 的 包,并且可以通过自动框选单个值来自动完成转换,但需要注意的是,这种自动转换并不扩展至数组。在本文中,我们将深入探讨在 Java 中将 byte 数组转换为 Byte 数组以及将 Byte 数组转换为 Byte 数组的不同方法。
2. Dependencies
2.依赖关系
To demonstrate one of the converting approaches, we’ll use the Apache Commons Lang library. Let’s add its dependency to our bytepom.xml:
为了演示其中一种转换方法,我们将使用 Apache Commons Lang 库。让我们将其依赖关系添加到我们的字节pom.xml中:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.14.0</version>
</dependency>
3. Byte.valueOf() and byteValue()
3. Byte.valueOf() 和 byteValue() .
The first approach we’ll explore is to use Byte.valueOf() and a byteValue() of a Byte object in a loop.
我们要探索的第一种方法是在循环中使用 Byte.valueOf() 和 Byte 对象的 byteValue() 。
3.1. Byte.valueOf()
3.1 Byte.valueOf()
Byte.valueOf(byte b) returns a Byte instance with a byte value sent in the input parameter of this method.
Byte.valueOf(byte b) 返回一个 Byte 实例,该实例具有本方法输入参数中发送的字节值。
Let’s convert each byte in the array into a wrapper object using Byte.valueOf(byte b) and iterating the array in a loop:
让我们使用 Byte.valueOf(byte b) 将数组中的每个 byte 转换为封装对象,并在循环中遍历数组:
private static final byte[] PRIMITIVE_BYTE_ARRAY = {65, 66, 67, 68};
private static final Byte[] EXPECTED_ARRAY_VALUES = {65, 66, 67, 68};
@Test
void givenPrimitiveByteArray_whenConvertingUsingByteValueOf_thenGiveExpectedResult() {
Byte[] newByteArray = new Byte[PRIMITIVE_BYTE_ARRAY.length];
for (int i = 0; i < PRIMITIVE_BYTE_ARRAY.length; i++) {
newByteArray[i] = Byte.valueOf(PRIMITIVE_BYTE_ARRAY[i]);
}
Assertions.assertThat(newByteArray)
.containsExactly(EXPECTED_ARRAY_VALUES);
}
As we can see, all the bytes were copied into new Byte[], and all the values remain in the same places.
我们可以看到,所有字节都被复制到了新的 Byte[] 中,并且所有值都保持在相同的位置。
3.2. Byte.byteValue()
3.2 Byte.byteValue().
The byteValue() of a Byte object returns a primitive byte value inside it. Let’s iterate the Byte[] and call this method for each element:
Byte 对象的 byteValue() 返回其内部的原始字节值。让我们遍历 Byte[] 并为每个元素调用此方法:
private static final byte[] EXPECTED_ARRAY_VALUES = {65, 66, 67, 68};
private static final Byte[] BYTE_ARRAY = {65, 66, 67, 68};
@Test
void givenByteArray_whenConvertingUsingByteValue_thenGiveExpectedResult() {
byte[] newByteArray = new byte[BYTE_ARRAY.length];
for (int i = 0; i < BYTE_ARRAY.length; i++) {
newByteArray[i] = BYTE_ARRAY[i].byteValue();
}
Assertions.assertThat(newByteArray)
.containsExactly(EXPECTED_ARRAY_VALUES);
}
As expected, we copied the bytes into the primitive array using unboxing.
不出所料,我们使用开箱方式将字节复制到了基元数组中。
4. Autoboxing and Unboxing
4.自动开箱和开箱
We can rewrite the code above in a more straightforward way using autoboxing to convert a byte value into a Byte instance and vice versa, utilizing unboxing.
我们可以使用自动开箱功能,将 byte 值转换为 Byte 实例,反之亦然,利用开箱功能,以更直接的方式重写上述代码。
If we disassemble our next code fragments – we can use the javap tool for this purpose – we’ll see that autoboxing calls the Byte.valueOf() method, while unboxing calls byteValue() of a Byte object under the hood. Therefore, technically, it’s the same logic with less code.
如果我们对接下来的代码片段进行反汇编(我们可以使用 javap 工具来实现这一目的),我们就会发现自动装箱调用了 Byte.valueOf() 方法,而开箱则调用了 Byte 对象的 byteValue() 方法。因此,从技术上讲,这是相同的逻辑,但代码更少。
4.1. Autoboxing
4.1.自动装箱
Let’s convert each byte in the array into a wrapper object using autoboxing and iterating the array in a loop:
让我们使用自动装箱将数组中的每个 byte 转换为封装对象,并在循环中遍历数组:
@Test
void givenPrimitiveIntArray_whenConvertingAutoboxing_thenGiveExpectedResult() {
Byte[] newByteArray = new Byte[PRIMITIVE_BYTE_ARRAY.length];
for (int i = 0; i < PRIMITIVE_BYTE_ARRAY.length; i++) {
newByteArray[i] = PRIMITIVE_BYTE_ARRAY[i];
}
Assertions.assertThat(newByteArray)
.containsExactly(EXPECTED_ARRAY_VALUES);
}
As we can see, all the bytes were copied into new Byte[], and all the values remain in the same places.
我们可以看到,所有字节都被复制到了新的 Byte[] 中,并且所有值都保持在相同的位置。
4.2. Unboxing
4.2.开箱
Now, we’ll perform the opposite operation and convert Byte[] into its primitive analog:
现在,我们将执行相反的操作,将 Byte[] 转换为其原始模拟:
@Test
void givenByteArray_whenConvertingUsingUnboxing_thenGiveExpectedResult() {
byte[] newByteArray = new byte[BYTE_ARRAY.length];
for (int i = 0; i < BYTE_ARRAY.length; i++) {
newByteArray[i] = BYTE_ARRAY[i];
}
Assertions.assertThat(newByteArray)
.containsExactly(EXPECTED_ARRAY_VALUES);
}
As expected, we copied the bytes into the primitive array using unboxing.
不出所料,我们使用开箱方式将字节复制到了基元数组中。
5. Arrays.setAll()
5. Arrays.setAll().
Since Java 8, we can simplify our code using Arrays.setAll(T[] array, IntFunction<? extends T> generator) instead of a loop. In the first parameter, we’ll send our target array, while in the second parameter, we will have a function that sets a new value for each element.
从 Java 8 开始,我们可以使用 Arrays.setAll(T[] array, IntFunction<? extends T> generator) 代替循环来简化代码。在第一个参数中,我们将发送目标数组,而在第二个参数中,我们将使用一个函数为每个元素设置一个新值。
Let’s rewrite our code for converting byte primitives array into Byte objects array using Arrays.setAll():
让我们重写代码,使用 Arrays.setAll() 将字节原数组转换为字节对象数组:</em
@Test
void givenPrimitiveByteArray_whenConvertingUsingAutoboxingAndArraysSetAll_thenGiveExpectedResult() {
Byte[] newByteArray = new Byte[PRIMITIVE_BYTE_ARRAY.length];
Arrays.setAll(newByteArray, n -> PRIMITIVE_BYTE_ARRAY[n]);
Assertions.assertThat(newByteArray)
.containsExactly(EXPECTED_ARRAY_VALUES);
}
As expected, we successfully converted values using even less code than previously.
不出所料,我们使用比以前更少的代码就成功地转换了数值。
6. ArrayUtils from Apache Commons Lang Library
6.来自 Apache Commons Lang 库的 ArrayUtils</span
ArrayUtils from the Apache Commons Lang library is a utility class that provides a variety of methods for working with arrays. We can use ArrayUtils.toObject(bytes[] bytes) to create an array of Byte objects from primitives, and conversely, we can create a byte array by calling ArrayUtils.toPrimitive(Byte[] byteObjects).
Apache Commons Lang 库中的 ArrayUtils 是一个实用程序类,它提供了多种处理数组的方法。我们可以使用 ArrayUtils.toObject(bytes[] bytes) 从基元创建一个 Byte 对象数组,反之,我们可以通过调用 ArrayUtils.toPrimitive(Byte[] byteObjects) 来创建一个字节数组。
6.1. ArrayUtils.toObject()
6.1.ArrayUtils.toObject()
Let’s convert our primitive bytes array into Byte[] using ArrayUtils.toObject():
让我们使用 ArrayUtils.toObject() 将原始 bytes 数组转换为 Byte[] :
@Test
void givenPrimitiveByteArray_whenConvertingUsingArrayUtils_thenGiveExpectedResult() {
Byte[] newByteArray = ArrayUtils.toObject(PRIMITIVE_BYTE_ARRAY);
Assertions.assertThat(newByteArray)
.containsExactly(EXPECTED_ARRAY_VALUES);
}
We successfully covered items in just one line of code.
我们只用一行代码就成功地涵盖了项目。
6.2. ArrayUtils.toPrimitive()
6.2.ArrayUtils.toPrimitive()
Now let’s perform the opposite operation using ArrayUtils.toPrimitive():
现在,让我们使用 ArrayUtils.toPrimitive() 执行相反的操作:
@Test
void givenByteArray_whenConvertingArrayUtils_thenGiveExpectedResult() {
byte[] newByteArray = ArrayUtils.toPrimitive(BYTE_ARRAY);
Assertions.assertThat(newByteArray)
.containsExactly(EXPECTED_ARRAY_VALUES);
}
We created a primitive bytes array from Byte[].
我们从 Byte[]. 中创建了一个原始 bytes 数组。
7. Conclusion
7.结论
In this article, we investigated multiple ways to convert a Byte to a byte array and vice versa. Which one to choose depends on the particular case. For the projects that already have Apache Commons in their dependencies, it probably makes sense to use ArrayUtils since it’s the shortest way to achieve the same result.
在本文中,我们研究了将 Byte 转换为字节数组(反之亦然)的多种方法。选择哪种方法取决于具体情况。对于依赖关系中已经包含 Apache Commons 的项目,使用 ArrayUtils 可能比较合理,因为这是实现相同结果的最简捷方法。
As usual, the full source code can be found over on GitHub.