2011-12-15 15 views
4

私はJavaでStringクラスの関数を理解しようとしています。だから、ここで簡単なコードされます:offsetByCodePointsが実際に引数として取るJava関数は何ですか?

/* 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コードポイントによって指定されたインデックスからオフセットされて、このString内のインデックスを返します。 indexおよびcodePointOffsetによって指定されたテキスト範囲内の対になっていないサロゲートは、それぞれ1つのコードポイントとしてカウントされます。

パラメータ:

index - インデックスが

codePointOffsetを相殺するために - だから我々はコードポイントに引数を与えないコードポイント

にオフセット。しかし、与えられた引数(0,6)では、例外なく、うまく動作します。しかし、コードポイント(7)は範囲外ですので、codePointAt()は失敗します。だから、関数がコード単位でargを取得するのでしょうか?または私は何かを逃した。

答えて

5

codePointAtは、charとなります。

インデックスは、char値(Unicodeコード単位)を指し、0からlength() - 1の範囲です。

この文字列には6つのコードポイントがあります。 offsetByCodePoints呼び出しは、char-index 7である6つのコードポイントの後にインデックスを返します。次に、文字列の最後にあるcodePointAt(7)を取得しようとします。なぜ、すべて0のコード・ポイントを過ぎてカウントするので、あなたはすべて0 charの過去カウントしなければならないものを

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

考える確認するには

これをあなたの文字列に外挿して、すべて6のコードポイントを超えないようにカウントするには、すべて7を過去に数えなければなりません。 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を返す!コードポイント(0から数えて)が最大のコードユニットのインデックスが6と5であると仮定すると、それはかなり奇妙に見えます。 –

+0

@UgnichenkoDmitriy、Ah。 javadocを読み返す際には、 'offsetByCodePoints'はcharインデックスを返します。私の投稿を編集しました。 –

+0

ああ、あなたは私を愚かだと呼ぶかもしれませんが、まだ得られない - この7(7)はどこから来ますか?最大のインデックスは6です。つまり、最初の文字(またはコード単位)のインデックスが0の場合です。しかし、7はどこから来ますか?うん、私たちは7つの文字を持っていますが、私が言ったように、インデックスでは少し違います。 –

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); 
    } 
} 
関連する問題