杰瑞科技汇

Java中byte数组转byte数组,如何高效实现?

简单的数组复制(最常见)

这是最基础的需求,你想创建一个新的 byte 数组,其内容与原数组完全相同,这在 Java 中有几种高效的方法。

Java中byte数组转byte数组,如何高效实现?-图1
(图片来源网络,侵删)

方法1: System.arraycopy() - 性能最优

这是最推荐的方法,因为它是一个本地方法,性能非常高,专门用于数组之间的复制。

public class ByteArrayCopy {
    public static void main(String[] args) {
        byte[] originalArray = {1, 2, 3, 4, 5};
        // 创建一个与原数组长度相同的新数组
        byte[] copiedArray = new byte[originalArray.length];
        // 使用 System.arraycopy 进行复制
        // 参数: 源数组, 源数组起始位置, 目标数组, 目标数组起始位置, 复制长度
        System.arraycopy(originalArray, 0, copiedArray, 0, originalArray.length);
        // 验证结果
        System.out.println("Original: " + Arrays.toString(originalArray));
        System.out.println("Copied:   " + Arrays.toString(copiedArray));
        // 修改原数组,不影响新数组
        originalArray[0] = 99;
        System.out.println("--- After modifying original ---");
        System.out.println("Original: " + Arrays.toString(originalArray));
        System.out.println("Copied:   " + Arrays.toString(copiedArray)); // 值未改变
    }
}

优点:

  • 性能最高:由 JVM 直接优化,速度最快。
  • 灵活性高:可以指定源数组和目标数组的起始位置以及复制的长度。

方法2: Arrays.copyOf() - 更简洁

java.util.Arrays.copyOf() 方法提供了更简洁的语法,内部也是调用 System.arraycopy() 实现的。

import java.util.Arrays;
public class ByteArrayCopyWithArrays {
    public static void main(String[] args) {
        byte[] originalArray = {1, 2, 3, 4, 5};
        // 使用 Arrays.copyOf 复制整个数组
        byte[] copiedArray = Arrays.copyOf(originalArray, originalArray.length);
        System.out.println("Original: " + Arrays.toString(originalArray));
        System.out.println("Copied:   " + Arrays.toString(copiedArray));
    }
}

优点:

Java中byte数组转byte数组,如何高效实现?-图2
(图片来源网络,侵删)
  • 代码简洁:一行代码即可完成。
  • 灵活性:可以轻松复制数组的部分内容(Arrays.copyOf(originalArray, 3) 会复制前3个元素)。

方法3: 克隆 (clone()) - 对象级别的复制

每个数组对象都有一个 clone() 方法,它会创建一个新数组,并将原数组的元素复制到新数组中。

public class ByteArrayClone {
    public static void main(String[] args) {
        byte[] originalArray = {1, 2, 3, 4, 5};
        // 使用 clone() 方法
        byte[] clonedArray = originalArray.clone();
        System.out.println("Original: " + Arrays.toString(originalArray));
        System.out.println("Cloned:   " + Arrays.toString(clonedArray));
    }
}

优点:

  • 语法简单:直接在数组对象上调用。

缺点:

  • 灵活性差:只能复制整个数组,无法指定范围。
  • 可读性:相比 Arrays.copyOfclone() 的意图可能不够明确。

带数据转换的复制

当“转换”不仅仅是复制,而是对数据进行某种处理时,就需要手动遍历和转换。

Java中byte数组转byte数组,如何高效实现?-图3
(图片来源网络,侵删)

示例:将每个字节的值乘以2

import java.util.Arrays;
public class ByteArrayTransform {
    public static void main(String[] args) {
        byte[] originalArray = {1, 2, 3, 4, 5};
        byte[] transformedArray = new byte[originalArray.length];
        for (int i = 0; i < originalArray.length; i++) {
            // 注意:这里直接相乘可能会溢出,但 byte 会自动回绕
            transformedArray[i] = (byte) (originalArray[i] * 2);
        }
        System.out.println("Original: " + Arrays.toString(originalArray));
        System.out.println("Transformed: " + Arrays.toString(transformedArray)); // [2, 4, 6, 8, 10]
    }
}

在这个场景下,我们创建了一个新数组,并通过循环将原数组中的每个元素处理后放入新数组。


处理不同编码的字符串转换

这是非常常见的需求,比如将一个 GBK 编码的 byte 数组转换成 UTF-8 编码的 byte 数组。

核心思想:

  1. 将源 byte 数组用其原始编码解码成 String
  2. 将这个 String 用目标编码重新编码成新的 byte 数组。

示例:GBK 转 UTF-8

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
public class ByteArrayEncodingConversion {
    public static void main(String[] args) {
        String originalString = "你好,世界"; // 包含中文字符
        // 1. 将字符串按 GBK 编码成 byte 数组
        byte[] gbkBytes = originalString.getBytes(Charset.forName("GBK"));
        System.out.println("GBK Bytes: " + Arrays.toString(gbkBytes));
        // 2. 将 GBK 的 byte 数组按 GBK 解码回 String
        String fromGbkString = new String(gbkBytes, Charset.forName("GBK"));
        System.out.println("Decoded from GBK: " + fromGbkString);
        // 3. 将这个 String 按 UTF-8 编码成新的 byte 数组
        byte[] utf8Bytes = fromGbkString.getBytes(StandardCharsets.UTF_8);
        System.out.println("UTF-8 Bytes: " + Arrays.toString(utf8Bytes));
        // 验证一下长度变化,GBK 对中文通常用2个字节,UTF-8 用3个
        System.out.println("GBK Bytes Length: " + gbkBytes.length);
        System.out.println("UTF-8 Bytes Length: " + utf8Bytes.length);
    }
}

注意:

  • 如果编码和解码的字符集不一致,很可能会导致乱码,从而得到错误的新 byte 数组。

加密/解密转换

在密码学领域,byte 数组之间的转换是核心操作,使用 AES 算法加密一个 byte 数组。

这通常需要使用第三方库,如 Bouncy Castle 或 Java 内置的 javax.crypto 包。

示例:使用 AES 加密(概念性代码)

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Arrays;
import java.util.Base64;
public class ByteArrayEncryption {
    // 注意:实际项目中密钥管理要非常小心,这里仅作演示
    private static final String AES_KEY = "ThisIsASecretKey123"; // 16, 24, or 32 bytes for AES-128, AES-192, AES-256
    public static byte[] encrypt(byte[] originalBytes) throws Exception {
        // 1. 生成密钥
        SecretKeySpec secretKey = new SecretKeySpec(AES_KEY.getBytes(StandardCharsets.UTF_8), "AES");
        // 2. 创建 Cipher 实例
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        // 3. 执行加密,得到加密后的 byte 数组
        byte[] encryptedBytes = cipher.doFinal(originalBytes);
        return encryptedBytes;
    }
    public static void main(String[] args) throws Exception {
        String originalString = "This is a secret message.";
        byte[] originalBytes = originalString.getBytes(StandardCharsets.UTF_8);
        System.out.println("Original Bytes: " + Arrays.toString(originalBytes));
        // 转换:原始 byte 数组 -> 加密后的 byte 数组
        byte[] encryptedBytes = encrypt(originalBytes);
        // Base64 编码方便打印,否则很多字节是不可见字符
        System.out.println("Encrypted Bytes (Base64): " + Base64.getEncoder().encodeToString(encryptedBytes));
    }
}

在这个例子中,encrypt 方法就是一个典型的“byte数组转byte数组”的转换,但它执行的是复杂的加密算法。


总结与最佳实践

场景 推荐方法 说明
简单复制 System.arraycopy() 性能最佳,适合性能敏感代码。
Arrays.copyOf() 代码最简洁,推荐在大多数业务代码中使用。
clone() 语法简单,但灵活性差,可读性略逊。
数据转换 for 循环 需要对每个元素进行逻辑处理时,手动遍历是唯一选择。
编码转换 String 作为桥梁 new String(bytes, charset) 解码,str.getBytes(newCharset) 编码。
加密/解密 专业加密库 (如 Bouncy Castle) 使用 Cipher 等类,遵循安全编码规范。

核心要点:

  1. 明确你的“转换”意图:你只是想复制一份,还是想对数据进行修改、编码或加密?
  2. 根据意图选择工具
    • 复制 -> Arrays.copyOf (首选) 或 System.arraycopy (性能优先)。
    • 处理 -> for 循环。
    • 编码 -> String 类的 getBytes() 和构造函数。
    • 加密 -> javax.crypto 或 Bouncy Castle。

希望这个详细的解释能帮助你更好地理解和处理 Java 中的 byte 数组转换问题!

分享:
扫描分享到社交APP
上一篇
下一篇