String#codePointAt(int)
について知っていますが、コードポイントオフセットではなく、char
オフセットでインデックス付けされています。
私は次のようなことをしようと考えています:
String#charAt(int)
を使用して、インデックスでchar
を取得しますchar
が 高代理範囲 にあるかどうかのテストString#codePointAt(int)
を使用してコードポイントを取得し、インデックスを2ずつ増やしますchar
値をコードポイントとして使用し、インデックスを1増やしますしかし、私の懸念は
char
値または1つの値として保存されるかどうかはわかりませんはい、JavaはStringsの内部表現にUTF-16風のエンコーディングを使用します。そして、はい、Basic Multilingual Plane( [〜#〜] bmp [ 〜#〜] )代理スキームを使用します。
BMP以外の文字を処理することがわかっている場合は、Java String:
final int length = s.length();
for (int offset = 0; offset < length; ) {
final int codepoint = s.codePointAt(offset);
// do something with the codepoint
offset += Character.charCount(codepoint);
}
Java 8が追加されました CharSequence#codePoints
は、コードポイントを含むIntStream
を返します。ストリームを直接使用して、それらを反復処理できます。
string.codePoints().forEach(c -> ...);
または、ストリームを配列に収集してforループを使用します。
for(int c : string.codePoints().toArray()){
...
}
これらの方法は、おそらく Jonathan Feinbergsのソリューション よりも高価ですが、読み取り/書き込みが高速であり、パフォーマンスの違いは通常わずかです。
Foreachループ( ref )で動作する回避方法を追加すると思いますが、さらにJava 8の新しい String#codePoints Java 8に移動すると簡単にメソッド:
次のようにforeachで使用できます:
for(int codePoint : codePoints(myString)) {
....
}
ヘルパーmthodは次のとおりです。
public static Iterable<Integer> codePoints(final String string) {
return new Iterable<Integer>() {
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
int nextIndex = 0;
public boolean hasNext() {
return nextIndex < string.length();
}
public Integer next() {
int result = string.codePointAt(nextIndex);
nextIndex += Character.charCount(result);
return result;
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
};
}
または、文字列をintの配列に変換するだけの場合(上記のアプローチよりも多くのRAMを使用する場合があります):
public static List<Integer> stringToCodePoints(String in) {
if( in == null)
throw new NullPointerException("got null");
List<Integer> out = new ArrayList<Integer>();
final int length = in.length();
for (int offset = 0; offset < length; ) {
final int codepoint = in.codePointAt(offset);
out.add(codepoint);
offset += Character.charCount(codepoint);
}
return out;
}
ありがたいことに「codePoints」を使用すると、UTF-16(Javaの内部文字列表現)の代理ペアを安全に処理できます。