使用Java语言进行Unicode代理编程(5)
时间:2010-11-20 IBM Masahiko Maedera
随机访问
随机访问是直接访问一个字符串中 的任意位置。当字符串被访问时,索引值基于 16 位 char 类型的单位。但是, 如果一个字符串使用 32 位码位,那么它不能使用一个基于 32 位码位的单位的 索引访问。必须使用 offsetByCodePoints() 来将码位的索引转换为 char 类型 的索引。如果算法设计很糟糕,这会导致很差的性能,因为 offsetByCodePoints() 总是通过使用第二个参数从第一个参数计算字符串的内 部。在这个小节中,我将比较三个示例,它们通过使用一个短单位来分割一个长 字符串。
示例 2-1:基准测试(不支持代理对)
清单 8 展示如 何使用一个宽度单位来分割一个字符串。这个基准测试留作后用,不支持代理对 。
清单 8. 不支持代理对
String[] sliceString(String str, int width) { // Example 2-1
// It must be that "str != null && width > 0".
List<String> slices = new ArrayList<String>();
int len = str.length(); // (1) the length of str
int sliceLimit = len - width; // (2) Do not slice beyond here.
int pos = 0; // the current position per char type
while (pos < sliceLimit) {
int begin = pos; // (3)
int end = pos + width; // (4)
slices.add(str.substring(begin, end));
pos += width; // (5)
}
slices.add(str.substring(pos)); // (6)
return slices.toArray(new String[slices.size()]); }
sliceLimit 变量对分割位置有所限制,以避免在剩余的字符串不足以分割当前宽度单位时抛 出一个 IndexOutOfBoundsException 实例。这种算法在当前位置超出 sliceLimit 时从 while 循环中跳出后再处理最后的分割。
示例 2-2: 使用一个码位索引
清单 9 展示了如何使用一个码位索引来随机访问一个 字符串:
清单 9. 糟糕的性能
String[] sliceString (String str, int width) { // Example 2-2
// It must be that "str != null && width > 0".
List<String> slices = new ArrayList<String>();
int len = str.codePointCount(0, str.length()); // (1) code point count [Modified]
int sliceLimit = len - width; // (2) Do not slice beyond here.
int pos = 0; // the current position per code point
while (pos < sliceLimit) {
int begin = str.offsetByCodePoints(0, pos); // (3) [Modified]
int end = str.offsetByCodePoints(0, pos + width); // (4) [Modified]
slices.add(str.substring(begin, end));
pos += width; // (5)
}
slices.add(str.substring (str.offsetByCodePoints(0, pos))); // (6) [Modified]
return slices.toArray(new String[slices.size()]); }
使用Java语言进行Unicode代理编程(6)
时间:2010-11-20 IBM Masahiko Maedera
清 单 9 修改了 清单 8 中的几行。首先,在 Line (1) 中,length() 被 codePointCount() 替代。其次,在 Lines ( |