Java中如何将代码点转换为UTF-8字节数组?
Java中将代码点转换为UTF-8字节数组的惯用方法
在Java里,把整数代码点转成UTF-8字节数组,最惯用且高效的标准库方案是使用CharsetEncoder,它能直接跳过创建中间String的步骤,减少内存开销,尤其适合批量处理或者对性能敏感的场景。
1. 高性能方案:使用CharsetEncoder
CharsetEncoder是NIO工具类,专门负责把字符/代码点编码成指定字符集的字节流,直接操作缓冲区,没有多余的对象创建。
单个代码点的转换示例:
import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.CharacterCodingException; import java.nio.charset.StandardCharsets; public class CodePointConverter { public static byte[] codePointToUtf8(int codePoint) throws CharacterCodingException { var encoder = StandardCharsets.UTF_8.newEncoder(); var charBuffer = CharBuffer.wrap(Character.toChars(codePoint)); var byteBuffer = encoder.encode(charBuffer); byte[] result = new byte[byteBuffer.remaining()]; byteBuffer.get(result); return result; } }
批量写入ByteArrayOutputStream的高效写法:
如果要把多个代码点直接整合到输出流里,这种方式能避免多次数组拷贝:
import java.io.ByteArrayOutputStream; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.CoderResult; import java.nio.charset.CharacterCodingException; import java.nio.charset.StandardCharsets; public class CodePointStreamWriter { public static void writeCodePointsToStream(ByteArrayOutputStream out, int... codePoints) throws CharacterCodingException { var encoder = StandardCharsets.UTF_8.newEncoder(); var charBuffer = CharBuffer.allocate(1024); // 可按需调整缓冲区大小 var byteBuffer = ByteBuffer.allocate(1024); for (int cp : codePoints) { charBuffer.put(Character.toChars(cp)); charBuffer.flip(); // 字节缓冲区满了就写入输出流 while (encoder.encode(charBuffer, byteBuffer, false) == CoderResult.OVERFLOW) { byteBuffer.flip(); out.write(byteBuffer.array(), 0, byteBuffer.remaining()); byteBuffer.clear(); } charBuffer.clear(); } // 处理剩余内容并刷新编码器 encoder.encode(charBuffer, byteBuffer, true); encoder.flush(byteBuffer); byteBuffer.flip(); out.write(byteBuffer.array(), 0, byteBuffer.remaining()); } }
2. 简单场景的简洁写法
如果只是处理单个代码点,且对性能要求不高,也可以用一行极简代码(本质依赖String,但代码量极少):
byte[] utf8Bytes = String.valueOf(Character.toChars(codePoint)).getBytes(StandardCharsets.UTF_8);
对比你之前的实现
你之前用StringBuilder.appendCodePoint()再转String、getBytes的方式,和上面的简洁写法逻辑类似,都会产生中间String对象。而CharsetEncoder直接操作缓冲区,避免了String的额外内存开销与拷贝,在处理大量代码点时性能优势会很明显。
内容的提问来源于stack exchange,提问作者rwallace
相关产品推荐
相关产品推荐

