Bal*_*usC 10 java byte character character-encoding
计算字符长度的最有效方法是什么,考虑字符编码?编码只在运行时才知道.例如,在UTF-8中,字符具有可变字节长度,因此需要单独确定每个字符.到目前为止,我已经想出了这个:
char c = getCharSomehow();
String encoding = getEncodingSomehow();
// ...
int length = new String(new char[] { c }).getBytes(encoding).length;
Run Code Online (Sandbox Code Playgroud)
但这在循环中是笨拙和低效的,因为new String每次都需要创建.我在Java API中找不到其他更有效的方法.有一个String#valueOf(char),但根据其来源,它基本上与上面相同.我想这可以通过像位移这样的按位操作来完成,但这是我的弱点,我不确定如何在这里考虑编码:)
如果您对此问题有疑问,请查看此主题.
char c = getCharSomehow();
String encoding = getEncodingSomehow();
CharsetEncoder encoder = Charset.forName(encoding).newEncoder();
// ...
int length = encoder.encode(CharBuffer.wrap(new char[] { c })).limit();
Run Code Online (Sandbox Code Playgroud)
然而正如@Stephen C指出的那样,这方面存在更多问题.例如,可能需要考虑组合/代理字符.但这是另一个需要在此步骤之前的步骤中解决的问题.
Bkk*_*rad 10
使用CharsetEncoder并重用CharBuffer作为输入,并使用ByteBuffer作为输出.
在我的系统上,以下代码需要25秒来编码100,000个单个字符:
Charset utf8 = Charset.forName("UTF-8");
char[] array = new char[1];
for (int reps = 0; reps < 10000; reps++) {
for (array[0] = 0; array[0] < 10000; array[0]++) {
int len = new String(array).getBytes(utf8).length;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,以下代码在4秒内完成相同的操作:
Charset utf8 = Charset.forName("UTF-8");
CharsetEncoder encoder = utf8.newEncoder();
char[] array = new char[1];
CharBuffer input = CharBuffer.wrap(array);
ByteBuffer output = ByteBuffer.allocate(10);
for (int reps = 0; reps < 10000; reps++) {
for (array[0] = 0; array[0] < 10000; array[0]++) {
output.clear();
input.clear();
encoder.encode(input, output, false);
int len = output.position();
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:为什么仇恨者会讨厌?
这是一个从CharBuffer读取并跟踪代理对的解决方案:
Charset utf8 = Charset.forName("UTF-8");
CharsetEncoder encoder = utf8.newEncoder();
CharBuffer input = //allocate in some way, or pass as parameter
ByteBuffer output = ByteBuffer.allocate(10);
int limit = input.limit();
while(input.position() < limit) {
output.clear();
input.mark();
input.limit(Math.max(input.position() + 2, input.capacity()));
if (Character.isHighSurrogate(input.get()) && !Character.isLowSurrogate(input.get())) {
//Malformed surrogate pair; do something!
}
input.limit(input.position());
input.reset();
encoder.encode(input, output, false);
int encodedLen = output.position();
}
Run Code Online (Sandbox Code Playgroud)