将char与代码点进行比较?

Gil*_*ili 34 java unicode

将代码点与Java角色进行比较的"正确"方法是什么?例如:

int codepoint = String.codePointAt(0);
char token = '\n';
Run Code Online (Sandbox Code Playgroud)

我知道我可能会这样做:

if (codepoint==(int) token)
{ ... }
Run Code Online (Sandbox Code Playgroud)

但这段代码看起来很脆弱.有没有比较正式的API方法codepointschars,或转换char到一个codepoint比较?

Chr*_*cks 44

一点背景:当Java出现在1995年时,该char类型基于原始的" Unicode 88 "规范,该规范限制为16位.一年后,当实施Unicode 2.0时,引入了代理字符的概念,超出了16位的限制.

Java内部代表StringUTF-16格式的所有内容.对于超过U + FFFF的代码点,代码点由代理对表示,即两个chars,第一个是高代理代码单元,(在范围内),第二个是低代理代码单元(在\ uDC00-\uDFFF范围内).

从早期开始,所有基本Character方法都基于一个代码点可以用一个表示的假设,char这就是方法签名的样子.我想保留当Unicode 2.0出现时没有改变的向后兼容性,并且在处理它们时需要谨慎.引用Java文档:

  • 仅接受char值的方法不支持增补字符.它们将代理范围中的char值视为未定义的字符.例如,Character.isLetter('\ uD840')返回false,即使后面跟着字符串中的任何低代理值的特定值也表示字母.
  • 接受int值的方法支持所有Unicode字符,包括补充字符.例如,Character.isLetter(0x2F81A)返回true,因为代码点值表示一个字母(CJK表意文字).

铸造char一个int,因为你的样品做,虽然工作正常.

  • http://java.sun.com/developer/technicalArticles/Intl/Supplementary/讨论了Java中代码点背后的设计决策. (2认同)

McD*_*ell 10

字符类包含与Unicode码点的工作许多有用的方法.注意返回字符数组的Character.toChars(int)之类的方法.如果您的代码点位于补充范围内,那么该数组的长度将为两个字符.

您希望如何比较值取决于您是否要支持所有Unicode值.此示例代码可用于通过一个字符串的代码点来迭代,测试,以查看是否有用于辅助字符MATHEMATICAL_FRAKTUR_CAPITAL_G匹配(? - U + 1D50A):

public final class CodePointIterator {

  private final String sequence;
  private int index = 0;

  public CodePointIterator(String sequence) {
    this.sequence = sequence;
  }

  public boolean hasNext() {
    return index < sequence.length();
  }

  public int next() {
    int codePoint = sequence.codePointAt(index);
    index += Character.charCount(codePoint);
    return codePoint;
  }

  public static void main(String[] args) {
    String sample = "A" + "\uD835\uDD0A" + "B" + "C";
    int match = 0x1D50A;
    CodePointIterator pointIterator = new CodePointIterator(sample);
    while (pointIterator.hasNext()) {
      System.out.println(match == pointIterator.next());
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

对于Java 8以上,可以使用CharSequence.codePoints():

public static void main(String[] args) {
  String sample = "A" + "\uD835\uDD0A" + "B" + "C";
  int match = 0x1D50A;
  sample.codePoints()
        .forEach(cp -> System.out.println(cp == match));
}
Run Code Online (Sandbox Code Playgroud)

我创建了一个来帮助处理Unicode字符串长度和有时需要处理的比较情况.