Java中的char
类型可以存储16位值,即可存储65536个不同的值。目前,Unicode(12.1)中有137929个字符。
为了处理这种情况,Java字符串被存储在UTF-16中,它是一种16位编码方式。大多数Unicode字符(称为代码点)都存储在单个16位值中。一些字符则存储在一对16位值中,称为代理对。
这意味着Unicode字符可能会以2个Java中的char
“字符”形式存储,这意味着如果您希望您的代码具有完整的Unicode字符支持,则无法将Unicode字符存储在单个char
值中。
它们可以存储在一个int
变量中,其中该值在Java中被称为代码点。然而,通常更容易将它们存储为一个String
。
在您的情况下,您似乎正在替换Unicode字符,因此使用正则表达式替换调用可能更好,例如:
s = s.replaceAll("[Zz]", "\uD83C\uDD89");
s = s.replaceAll("[Zz]", "");
更新
如果您想要保留一种确定替换值的方法,您可以这样做:
s = Pattern.compile(".").matcher(s).replaceAll(mr -> getSpecialCharEighth(mr.group()));
private static String getSpecialCharEighth(String s) {
int cp = s.codePointAt(0);
if (cp >= 'A' && cp <= 'Z')
return Character.toString(cp - 'A' + 0x1f170);
if (cp >= 'a' && cp <= 'z')
return Character.toString(cp - 'a' + 0x1f170);
return s;
}
注意: replaceAll(replacer)
适用于Java 9及以上版本,Character.toString(codePoint)
适用于Java 11及以上版本。
更新2
由于该问题标记有android
,因此Java 9和Java 11的API不可用,以下是适用于Java 7及以上版本的解决方案。
StringBuffer buf = new StringBuffer(s.length() + 16);
Matcher m = Pattern.compile(".").matcher(s);
while (m.find())
m.appendReplacement(buf, getSpecialCharEighth(m.group()));
s = m.appendTail(buf).toString();
private static String getSpecialCharEighth(String s) {
int cp = s.codePointAt(0);
if (cp >= 'A' && cp <= 'Z')
return new String(new int[] { cp - 'A' + 0x1f170 }, 0, 1);
if (cp >= 'a' && cp <= 'z')
return new String(new int[] { cp - 'a' + 0x1f170 }, 0, 1);
return s;
}
当s = "Hello World!"
时的结果:
!
char
类型来处理它。 - Felix