ram*_*ion 99 java string unicode
所以我知道String#codePointAt(int),但它是由char偏移索引,而不是由代码点偏移索引.
我正在考虑尝试这样的事情:
String#charAt(int)得到char的指数char在高代理范围内
String#codePointAt(int)获取代码点,并将索引增加2char值作为代码点,并将索引递增1但我担心的是
char值或一个值Jon*_*erg 138
是的,Java使用UTF-16-esque编码来表示字符串的内部表示,是的,它使用代理方案对基本多语言平面(BMP)之外的字符进行编码.
如果你知道你将处理BMP之外的字符,那么这是迭代Java字符串字符的规范方法:
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);
}
Run Code Online (Sandbox Code Playgroud)
Ale*_*lex 62
Java 8添加CharSequence#codePoints了返回IntStream包含代码点的内容.您可以直接使用流来迭代它们:
string.codePoints().forEach(c -> ...);
Run Code Online (Sandbox Code Playgroud)
或者通过将流收集到数组中使用for循环:
for(int c : string.codePoints().toArray()){
...
}
Run Code Online (Sandbox Code Playgroud)
这些方法可能比Jonathan Feinbergs的解决方案更昂贵,但它们的读/写速度更快,性能差异通常无关紧要.
以为我会添加一个与foreach循环(ref)一起使用的变通方法,并且当你转移到java 8时,你可以轻松地将它转换为java 8的新String#codePoints方法:
您可以将它与foreach一起使用,如下所示:
for(int codePoint : codePoints(myString)) {
....
}
Run Code Online (Sandbox Code Playgroud)
这是助手方法:
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();
}
};
}
};
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您只想将字符串转换为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;
}
Run Code Online (Sandbox Code Playgroud)
谢天谢地,使用"codePoints"安全地处理UTF-16的代理配对(java的内部字符串表示).
迭代代码点是作为Sun的功能请求提交的.
还有一个关于如何在那里迭代String CodePoints的例子.