2011-12-15 138 views
4

我想了解一些在Java中的String类的功能。所以,这里是一个简单的代码:什么Java函数offsetByCodePoints真的需要作为参数?

/* different experiments with String class */ 

public class TestStrings { 
    public static void main(String[] args) { 
     String greeting = "Hello\uD835\uDD6b"; 

     System.out.println("Number of code units in greeting is " + greeting.length()); 
     System.out.println("Number of code points " + greeting.codePointCount(0,greeting.length())); 

     int index = greeting.offsetByCodePoints(0,6); 
     System.out.println("index = " + index); 
     int cp = greeting.codePointAt(index); 
     System.out.println("Code point at index is " + (char) cp); 
    } 
} 

\ uD835 \ uDD6b是ℤ象征,所以这是确定代理对。

所以,字符串有6(6)个代码点和7(7)个代码单元(2字节的字符)。由于它在文档:

offsetByCodePoints

public int offsetByCodePoints(int index, 
           int codePointOffset) 

返回此字符串,它是由代码codePointOffset个点给定索引偏移中的索引。 由index和codePointOffset给出的文本范围内的未配对替代项每个都计为一个代码点。

参数:

index - 要抵消

codePointOffset指数 - 中码点的偏移

所以我们做让步代码点参数。但是,对于给定的参数(0,6),它仍然正常工作,没有例外。但codePointAt()失败,因为它返回7出界。所以,也许该函数获取代码单元的参数?或者我错过了一些东西。

回答

5

codePointAt需要char索引。

该索引引用char值(Unicode代码单元),范围从0length() - 1

该字符串中有六个代码点。调用offsetByCodePoints将返回6个代码点之后的索引,即char-index 7.然后尝试获取位于该字符串末尾的codePointAt(7)

想知道为什么,考虑什么

"".offsetByCodePoints(0, 0) == 0 

因为计算过去所有0码点,你要算过去所有0 char秒。

将其推断为您的字符串,要计算过去所有6代码点,您必须计算过去所有的7 char s。

在使用中可能会看到codePointAt会使这一点变得清晰。这是遍历所有代码点在字符串中的惯用方式(或CharSequence):

for (var charIndex = 0, nChars = s.length(), codepoint; 
    charIndex < nChars; 
    charIndex += Character.charCount(codepoint)) { 
    codepoint = s.codePointAt(charIndex); 
    // Do something with codepoint. 
} 
+0

谢谢!但关于讨论代码的*奇怪的事情是int index = greeting.offsetByCodePoints(0,6);实际上不是6,而是7!这看起来很奇怪,假设代码点的最大代码单元的索引是6和5(从0开始计数)。 – 2011-12-15 17:45:30

0

有用的答案,迈克......为了便于理解String#offsetByCodePoints,我评论它的使用和修改了一下这个问题例如:

我个人发现这里的Java文档含糊不清。

public class TestStrings 
{ 
    public static void main(String[] args) 
    { 
     String greeting = "Hello\uD835\uDD6b"; 

     // Gets the `char` index a.k.a. offset of the code point 
     // at the code point index `0` starting from the `char` index `6`¹. 
     // --- 
     // Since `6` refers to an "unpaired" low surrogate (\uDD6b), the 
     // returned value is 6 + 1 = 7. 
     // 
     int charIndex = greeting.offsetByCodePoints(0,6); 

     System.out.println("charIndex = " + charIndex); 

     int cp = greeting.codePointAt(charIndex); 
     System.out.println("Code point at index is " + (char) cp); 
    } 
} 
相关问题