Ich weiß also Bescheid String#codePointAt(int)
, aber es wird durch den char
Versatz indiziert , nicht durch den Codepunktversatz.
Ich denke darüber nach, etwas zu versuchen wie:
- Verwenden Sie
String#charAt(int)
, um diechar
an einem Index zu erhalten - Testen, ob der
char
im Bereich der hohen Surrogate liegt- Wenn ja, verwenden Sie
String#codePointAt(int)
, um den Codepunkt abzurufen, und erhöhen Sie den Index um 2 - Wenn nicht, verwenden Sie den angegebenen
char
Wert als Codepunkt und erhöhen Sie den Index um 1
- Wenn ja, verwenden Sie
Aber meine Bedenken sind
- Ich bin nicht sicher, ob Codepunkte, die sich natürlich im Bereich mit hohen Ersatzwerten befinden, als zwei
char
oder als ein Wert gespeichert werden - Dies scheint eine schrecklich teure Möglichkeit zu sein, Zeichen zu durchlaufen
- jemand muss sich etwas Besseres ausgedacht haben.
offset = s.offsetByCodePoints(offset, 1);
. Gibt es einen Vorteil bei der Verwendungoffset += Character.charCount(codepoint);
stattdessen?charAt()
eine schlechte Idee einsetztJava 8 hinzugefügt,
CharSequence#codePoints
das eineIntStream
enthält, die die Codepunkte enthält. Sie können den Stream direkt verwenden, um darüber zu iterieren:oder mit einer for-Schleife durch Sammeln des Streams in einem Array:
Diese Methoden sind wahrscheinlich teurer als die Lösung von Jonathan Feinbergs , aber sie sind schneller zu lesen / schreiben und der Leistungsunterschied ist normalerweise unbedeutend.
quelle
for (int c : (Iterable<Integer>) () -> string.codePoints().iterator())
funktioniert auch.for (int c : (Iterable<Integer>) string.codePoints()::iterator) ...
Das Iterieren über Codepunkte wird als Feature-Anfrage bei Sun abgelegt.
Siehe Sun Bug Entry
Es gibt auch ein Beispiel, wie Sie dort über String CodePoints iterieren können.
quelle
Ich dachte, ich würde eine Workaround-Methode hinzufügen, die mit foreach-Schleifen ( ref ) funktioniert , und Sie können sie in die neuen String # codePoints von Java 8 konvertieren einfach in Methode von Java 8 , wenn Sie zu Java 8 wechseln:
Sie können es mit foreach wie folgt verwenden:
Hier ist der Helfer:
Oder alternativ, wenn Sie nur eine Zeichenfolge in ein Array von int konvertieren möchten (das möglicherweise mehr RAM als der oben beschriebene Ansatz benötigt):
Glücklicherweise verwendet "codePoints" sicher die Ersatzpaarung von UTF-16 (Java's interne String-Darstellung).
quelle