java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > java字符与Unicode码转换

java实现字符与Unicode码转换(附源码)

作者:Katie。

在 Java 开发中,经常需要在字符(char 或 String)与其对应的Unicode 码点(int)之间进行相互转换,下面小编就来和大家详细介绍一下具体实现方法吧

一、项目背景详细介绍

在 Java 开发中,经常需要在字符charString)与其对应的Unicode 码点int)之间进行相互转换,以满足以下场景:

因此,提供一套简洁易用的 Java 工具,以便在字符↔码点、码点↔Unicode 转义序列之间互转,对于提高开发效率和保证编码安全具有重要意义。

二、项目需求详细介绍

1.字符到码点

2.码点到字符

3.字符串编码/解码

4.易用 API

工具类 UnicodeUtils

List<Integer> toCodePoints(String text);
String toHexCodes(String text);
String toUnicodeEscapes(String text);
String fromUnicodeEscapes(String escapes);
char fromCodePoint(int codePoint);

5.边界与错误处理

6.性能与线程安全

三、相关技术详细介绍

1.Java 字符与码点 API

2.字符串转义与正则

3.错误与异常

4.性能考虑

四、实现思路详细介绍

1.提取码点

toCodePoints(String):遍历 text.codePoints(),收集至 List<Integer>

toHexCodes:在 toCodePoints 基础上,将每个 int 格式化为 String.format("0x%04X", cp)

2.生成转义序列

toUnicodeEscapes(String):对每个码点,若 <0x10000\uXXXX,否则先 toChars 得到代理对,再分别转义。

3.解析转义

fromUnicodeEscapes(String):使用正则查找 \\uXXXX,对每个匹配组 XXXX 调用 Integer.parseInt(...,16) 转为 char,替换原文;

4.单点转换

fromCodePoint(int):校验范围后返回 Character.toChars(codePoint)[0] 或代理对组合。

/*
 * =====================================================
 * File: UnicodeUtils.java
 * 工具类:字符 ↔ Unicode 码点 转换与转义
 * =====================================================
 */
package com.example.unicode;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public final class UnicodeUtils {
    private static final Pattern UNICODE_ESCAPE = Pattern.compile("\\\\u([0-9A-Fa-f]{4})");

    private UnicodeUtils() { /* 禁止实例化 */ }

    /**
     * 将字符串拆分为码点列表
     */
    public static List<Integer> toCodePoints(String text) {
        if (text == null) return Collections.emptyList();
        return text.codePoints()
                   .boxed()
                   .collect(Collectors.toList());
    }

    /**
     * 将字符串转换为十六进制码点表示,如 "0x4E2D 0x6587"
     */
    public static String toHexCodes(String text) {
        return toCodePoints(text).stream()
            .map(cp -> String.format("0x%04X", cp))
            .collect(Collectors.joining(" "));
    }

    /**
     * 将字符串编码为 Unicode 转义序列,如 "\\u4E2D\\u6587"
     */
    public static String toUnicodeEscapes(String text) {
        if (text == null) return "";
        StringBuilder sb = new StringBuilder();
        for (int cp : text.codePoints().toArray()) {
            if (cp <= 0xFFFF) {
                sb.append(String.format("\\u%04X", cp));
            } else {
                // 代理对
                char[] surrogates = Character.toChars(cp);
                sb.append(String.format("\\u%04X", (int) surrogates[0]));
                sb.append(String.format("\\u%04X", (int) surrogates[1]));
            }
        }
        return sb.toString();
    }

    /**
     * 将含有 Unicode 转义序列的字符串还原
     */
    public static String fromUnicodeEscapes(String escapes) {
        if (escapes == null) return "";
        Matcher m = UNICODE_ESCAPE.matcher(escapes);
        StringBuffer sb = new StringBuffer();
        while (m.find()) {
            String hex = m.group(1);
            int cp = Integer.parseInt(hex, 16);
            m.appendReplacement(sb, new String(Character.toChars(cp)));
        }
        m.appendTail(sb);
        return sb.toString();
    }

    /**
     * 从单个码点构造字符(仅 BMP)
     */
    public static char fromCodePoint(int codePoint) {
        if (codePoint < Character.MIN_CODE_POINT || codePoint > Character.MAX_CODE_POINT) {
            throw new IllegalArgumentException(
                "码点超出范围: " + codePoint);
        }
        if (codePoint <= 0xFFFF) {
            return (char) codePoint;
        }
        // 非 BMP 码点,返回第一个代理项
        return Character.toChars(codePoint)[0];
    }
}

代码详细解读

1.toCodePoints(String)

使用 String.codePoints() 获取 UTF-16 编码下的所有码点,装箱为 List<Integer> 返回。

2.toHexCodes(String)

基于码点列表,将每个码点格式化为 "0x%04X" 并以空格分隔,便于调试查看。

3.toUnicodeEscapes(String)

4.fromUnicodeEscapes(String)

5.fromCodePoint(int)

校验码点范围,若在 BMP 区间则返回单个 char;如超出,则返回对应的第一个代理项(一般不建议仅取一半,使用 toChars 全面处理)。

项目详细总结

本工具类 UnicodeUtils 提供了字符 ↔ 码点Unicode 转义的双向转换方法:

项目常见问题及解答

为何要区分 BMP 与辅助平面?

Java char 为 UTF-16 单元,BMP 码点对应单个 char,辅助平面需使用代理对(两个 char)。

fromCodePoint 为什么只返回第一个代理项?

该方法示例仅展示如何校验并返回 char;如需全字符,应使用 Character.toChars 并处理完整 char[]

转义序列中的大写 X 与小写 x 有区别?

Java 标准仅支持 \u 小写,后续的 4 位十六进制不区分大小写。

非法转义序列如何处理?

本实现只替换匹配的合法 \uXXXX,其它内容保留原文;若需严格校验,可在替换后检查剩余反斜杠。

性能瓶颈在哪里?

正则替换和流式码点处理会在大文本中产生较多对象,可考虑复用 Matcher 或使用低级循环优化。

扩展方向与性能优化

全代理对支持

改进 fromCodePoint 返回完整 String,而非单个 char,确保辅助平面字符完整;

并行流处理

对超大文本可用 text.codePoints().parallel().mapToObj(...) 并行转换,提升吞吐;

自定义转义格式

支持 &#xXXXX;&#DDDD; HTML/XML 风格的 Unicode 表示;

API 丰富

增加 toDecimalCodes 输出十进制码点列表;

增加 escapeNonAscii 仅转义非 ASCII 字符。

工具集成

将该工具打包为 CLI 应用,或集成到 Web UI 前端,实时显示字符与码点对应关系。

到此这篇关于java实现字符与Unicode码转换(附源码)的文章就介绍到这了,更多相关java字符与Unicode码转换内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文