1. 概述
尽管Byte
是byte
基本类型的包装类,且单个值的自动转换可以通过自动装箱(autoboxing)来完成,但值得注意的是,这种自动转换并不适用于数组。本文将深入探讨在Java中将byte
数组转换为Byte
数组以及反之的操作方法。
2. 依赖
为了演示一种转换方法,我们将使用Apache Commons Lang库。让我们在pom.xml
中添加其依赖:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.14.0</version>
</dependency>
3. Byte.valueOf()
和 byteValue()
我们将首先探索使用Byte.valueOf()
和Byte
对象的byteValue()
方法在循环中进行转换。
3.1. Byte.valueOf()
Byte.valueOf(byte b)
方法返回一个带有输入参数byte
值的Byte
实例。
让我们使用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);
}
如我们所见,所有字节都被复制到新的Byte[]
中,且所有值都保留在原位置。
3.2. Byte.byteValue()
Byte
对象的byteValue()
方法返回其中包含的基本byte
值。让我们遍历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);
}
正如预期,我们使用反装箱将字节复制到了基本数组中。
4. 自动装箱与反装箱
我们可以使用自动装箱和反装箱更直接地重写上面的代码,以在必要时将byte
值转换为Byte
实例,反之亦然。
如果我们分解接下来的代码片段,我们可以使用javap
工具查看它们的底层实现——自动装箱实际上是调用了Byte.valueOf()
方法,而反装箱则是在Byte
对象上调用byteValue()
方法。因此,从技术上讲,这是相同的逻辑,只是代码更简洁。
4.1. 自动装箱
让我们使用自动装箱将数组中的每个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);
}
正如我们所见,所有字节都被复制到新的Byte[]
中,且所有值都保留在原位置。
4.2. 反装箱
现在,我们将执行相反的操作,将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);
}
正如预期,我们使用反装箱将字节复制到了基本数组中。
5. Arrays.setAll()
从Java 8开始,我们可以使用Arrays.setAll(T[] array, IntFunction<? extends T> generator)
简化代码,无需循环。 在第一个参数中,我们将发送目标数组,第二个参数是一个函数,用于为每个元素设置新值。
让我们使用Arrays.setAll()
将基本byte
数组转换为Byte
对象数组:
@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);
}
正如预期,我们使用更少的代码成功地进行了转换。
6. Apache Commons Lang库的ArrayUtils
Apache Commons Lang库中的ArrayUtils
是一个提供处理数组各种方法的实用工具类。我们可以使用ArrayUtils.toObject(bytes[] bytes)
将基本数组转换为Byte
对象数组,反过来,可以使用ArrayUtils.toPrimitive(Byte[] byteObjects)
创建基本byte
数组。
6.1. 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);
}
我们仅用一行代码就成功完成了转换。
6.2. ArrayUtils.toPrimitive()
现在,让我们使用ArrayUtils.toPrimitive()
执行相反操作:
@Test
void givenByteArray_whenConvertingArrayUtils_thenGiveExpectedResult() {
byte[] newByteArray = ArrayUtils.toPrimitive(BYTE_ARRAY);
Assertions.assertThat(newByteArray)
.containsExactly(EXPECTED_ARRAY_VALUES);
}
我们从Byte[]
创建了一个基本bytes
数组。
7. 总结
在这篇文章中,我们研究了多种将Byte
转换为byte
数组以及反之的操作方式。选择哪种方法取决于具体场景。对于已经包含Apache Commons库的项目,使用ArrayUtils
可能是更合理的选择,因为它是最简短的实现方式。
如往常一样,完整的源代码可以在GitHub上找到。