如何循环访问 Java 字符串的 unicode 代码点?

2022-08-31 09:20:39

所以我知道 String#codePointAt(int),但它是按偏移量而不是代码点偏移量编制索引的。char

我正在考虑尝试这样的事情:

但我担心的是

  • 我不确定自然位于高代理项范围内的代码点是存储为两个值还是一个值char
  • 这似乎是一种非常昂贵的迭代字符的方式
  • 一定有人想出了更好的东西。

答案 1

是的,Java使用UTF-16式编码作为字符串的内部表示,是的,它使用代孕方案对基本多语言平面(BMP)之外的字符进行编码。

如果您知道您将处理 BMP 之外的字符,那么以下是迭代 Java 字符串字符的规范方法:

final int length = s.length();
for (int offset = 0; offset < length; ) {
   final int codepoint = s.codePointAt(offset);

   // do something with the codepoint

   offset += Character.charCount(codepoint);
}

答案 2

Java 8 添加了 CharSequence#codePoints,它返回一个包含代码点的。您可以直接使用流来循环访问它们:IntStream

string.codePoints().forEach(c -> ...);

或者通过将流收集到数组中来使用 for 循环:

for(int c : string.codePoints().toArray()){
    ...
}

这些方法可能比Jonathan Feinbergs的解决方案更昂贵,但它们读/写速度更快,性能差异通常微不足道。