String.codePointAt这个方法到底是做什么的?

35

最近,我遇到了Java中的String类的codePointAt方法。我还发现了其他一些codePoint方法:codePointBeforecodePointCount等。它们肯定与Unicode有关,但我并不理解。

现在我想知道何时以及如何使用codePointAt和类似的方法。

4个回答

54

简短回答: 它给出了在String中指定索引处开始的Unicode代码点。 即该位置字符的“Unicode编号”。

更详细的解释: Java创建时只使用16位(也称为char)就足以容纳任何已存在的Unicode字符(这些部分现在被称为基本多语言面板或BMP)。 稍后,Unicode扩展以包括具有大于2 16 的代码点的字符。 这意味着char不再能够保存所有可能的Unicode代码点。

UTF-16是解决方案:它将“旧”Unicode代码点存储在16位中(即恰好一个char),并将所有新的Unicode代码点存储在32位中(即两个char值)。这两个16位值被称为“代理对”。现在严格来说,char保存的是“UTF-16代码单元”而不是“Unicode字符”,就像以前一样,所有“旧”的方法(仅处理char)仍然可以正常使用,只要您不使用任何“新”的Unicode字符(或者根本不关心它们),但是如果您也关心新字符(或者需要完整的Unicode支持),那么您将需要使用“代码点”版本,它实际上支持所有可能的Unicode代码点。

注意:一个非常著名的Unicode字符集中不包含基本多文种平面(BMP)的例子是表情符号:即使是简单的Grinning Face U+1F600也不能用单个char表示。

请您提供一个例子,其中charAt()无法提供完整的代码点,但是codePointAt()可以成功地提供。 - Zaid Khan
对于Zaid Khan:String s3 =“\ u0041 \ u00DF \ u6771 \uD801\uDC00”; System.out.println(s3.charAt(3)); System.out.println(s3.codePointAt(3)); - user1643352

6

代码点支持65535以上的字符,即Character.MAX_VALUE。

如果您的文本包含这样高的字符,则必须使用代码点或int而不是char进行处理。

它通过支持UTF-16实现,可以使用一个或两个16位字符并将其转换为int

据我所知,通常仅需要对最近添加的补充多语言补充表意文字字符进行此操作,例如非传统汉字。


6
好的,不仅限于非传统汉字:https://en.wikipedia.org/wiki/Plane_(Unicode) 许多较少人知道的语言、一些数学符号、表情符号以及几乎所有最近引入Unicode的内容都存在于BMP之外。这里有一个相关的问题(https://dev59.com/lG035IYBdhLWcg3wMNCW)。 - Joachim Sauer

2

下面的代码示例有助于澄清使用codePointAt的方法

    String myStr = "13";
    System.out.println(myStr.length()); // print 4, because  is two char
    System.out.println(myStr.codePointCount(0, myStr.length())); //print 3, factor in all unicode
    
    int result = myStr.codePointAt(0);
    System.out.println(Character.toChars(result)); // print 1
    
    result = myStr.codePointAt(1);
    System.out.println(Character.toChars(result)); // print , because codePointAt will get surrogate pair (high and low)
    
    result = myStr.codePointAt(2);
    System.out.println(Character.toChars(result)); // print low surrogate of  only, in this case it show "?"
    
    result = myStr.codePointAt(3);
    System.out.println(Character.toChars(result)); // print 3

0

2
这些方法与字符集没有直接关系(除了我不知道有哪些非通用字符集编码BMP之外的任何内容)。 - Joachim Sauer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接