我必须使用上面的代码点0FFFF
(特别是数学脚本字符)并且尚未找到有关如何执行此操作的简单教程。我希望能够 (a) 创建String
s 具有高代码点,并且 (b) 迭代其中的字符。自从char
不能保留这些点我的代码如下所示:
@Test
public void testSurrogates() throws IOException {
// creating a string
StringBuffer sb = new StringBuffer();
sb.append("a");
sb.appendCodePoint(120030);
sb.append("b");
String s = sb.toString();
System.out.println("s> "+s+" "+s.length());
// iterating over string
int codePointCount = s.codePointCount(0, s.length());
Assert.assertEquals(3, codePointCount);
int charIndex = 0;
for (int i = 0; i < codePointCount; i++) {
int codepoint = s.codePointAt(charIndex);
int charCount = Character.charCount(codepoint);
System.out.println(codepoint+" "+charCount);
charIndex += charCount;
}
}
我觉得这要么是完全正确的,要么是最干净的方法。我本来期望这样的方法codePointAfter()
但只有一个codePointBefore()
。请确认这是正确的策略或提供替代策略。
更新:感谢@Jon 的确认。我为此苦苦挣扎——这里有两个需要避免的错误:
- 没有代码点的直接索引(即没有
s.getCodePoint(i))
- 你必须迭代它们
- using
(char)
因为强制转换会截断上面的整数0FFFF
而且不容易发现
对我来说这看起来是正确的。如果您想迭代字符串中的代码点,您可以将此代码包装在Iterable
:
public static Iterable<Integer> getCodePoints(final String text) {
return new Iterable<Integer>() {
@Override public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
private int nextIndex = 0;
@Override public boolean hasNext() {
return nextIndex < text.length();
}
@Override public Integer next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
int codePoint = text.codePointAt(nextIndex);
nextIndex += Character.charCount(codePoint);
return codePoint;
}
@Override public void remove() {
throw new UnsupportedOperationException();
}
};
}
};
}
或者您可以更改方法以仅返回int[]
当然:
public static int[] getCodePoints(String text) {
int[] ret = new int[text.codePointCount(0, text.length())];
int charIndex = 0;
for (int i = 0; i < ret.length; i++) {
ret[i] = text.codePointAt(charIndex);
charIndex += Character.charCount(ret[i]);
}
return ret;
}
我同意,遗憾的是 Java 库还没有公开这样的方法,但至少它们没有too很难写。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)