教学文库网 - 权威文档分享云平台
您的当前位置:首页 > 精品文档 > 政务民生 >

JAVA 技术文章收集(4)

来源:网络收集 时间:2026-07-25
导读: ? ? ? ? static boolean isHighSurrogate(char ch) static boolean isLowSurrogate(char ch) static boolean isSurrogatePair(char high, char low) static int toCodePoint(char high, char low) String 类: ? 1-

? ? ? ? static boolean isHighSurrogate(char ch) static boolean isLowSurrogate(char ch) static boolean isSurrogatePair(char high, char low) static int toCodePoint(char high, char low) String 类: ? 1-3 基本支持 5687 2.80 ? ? int codePointAt(int index) int codePointCount(int begin, int end) int offsetByCodePoints(int index, int cpOffset) 使用 1-4 codePointBefore() 的5516 2.72 基本支持 使用 charCount() 的优1-5 3406 1.68 化支持 String 类: ? int codePointBefore(int index) Character 类: ? static int charCount(int cp) Character 类: ? ? 使用一个 char 数组的1-6 3062 1.51 优化支持 static int codePointAt(char[] ach, int index) static int codePointCount(char[] ach, int offset, int count) Character 类: ? 使用 CharSequence 的1-7 4360 2.15 面向对象方法 ? static int codePointAt(CharSequence seq, int index) static int codePointCount(CharSequence seq, int begin, int end) 2、 随机访问 随机访问是直接访问一个字符串中的任意位置。当字符串被访问时,索引值基于 16 位 char 类型的单位。但是,如果一个字符串使用 32 位码位,那么它不能使用一个基于 32 位

码位的单位的索引访问。必须使用 offsetByCodePoints() 来将码位的索引转换为 char 类型的索引。如果算法设计很糟糕,这会导致很差的性能,因为 offsetByCodePoints() 总是通过使用第二个参数从第一个参数计算字符串的内部。在这个小节中,我将比较三个示例,它们通过使用一个短单位来分割一个长字符串。

示例 2-1:基准测试(不支持代理对)

清单 8 展示如何使用一个宽度单位来分割一个字符串。这个基准测试留作后用,不支持代理对。

清单 8. 不支持代理对

String[] sliceString(String str, int width) { // Example 2-1 // It must be that \ List slices = new ArrayList(); 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 \ List slices = new ArrayList(); 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()]); } 清单 9 修改了 清单 8 中的几行。首先,在 Line (1) 中,length() 被 codePointCount() 替代。其次,在 Lines (3)、(4) 和 (6) 中,char 类型的索引通过 offsetByCodePoints() 用码位索引替代。

基本的算法流与 示例 2-1 中的看起来几乎一样。但处理时间根据字符串长度与示例 2-1 的比率同比增加,因为 offsetByCodePoints() 总是从字符串头到指定索引计算字符串内部。

示例 2-3:减少的处理时间

可以使用清单 10 中展示的方法来避免 示例 2-2 的性能问题: 清单 10. 改进的性能

String[] sliceString(String str, int width) { // Example 2-3 // It must be that \ List slices = new ArrayList(); int len = str.length(); // (1) the length of str int sliceLimit // (2) Do not slice beyond here. [Modified] = (len >= width * 2 || str.codePointCount(0, len) > width) ? str.offsetByCodePoints(len, -width) : 0; int pos = 0; // the current position per char type while (pos < sliceLimit) { int begin = pos; // (3) int end = str.offsetByCodePoints(pos, width); // (4) [Modified] slices.add(str.substring(begin, end)); pos = end; // (5) [Modified] } slices.add(str.substring(pos)); // (6) return slices.toArray(new String[slices.size()]); } 首先,在 Line (2) 中,(清单 9 中的)表达式 len-width 被 offsetByCodePoints(len,-width) 替代。但是,当 width 的值大于码位的数量时,这会抛出一个 IndexOutOfBoundsException 实

例。必须考虑边界条件以避免异常,使用一个带有 try/catch 异常处理程序的子句将是另一个解决方案。如果表达式 len>width*2 为 true,则可以安全地调用 offsetByCodePoints(),因为即使所有码位都被转换为代理对,码位的数量仍会超过 width 的值。或者,如果 codePointCount(0,len)>width 为 true,也可以安全地调用 offsetByCodePoints()。如果是其他情况,sliceLimit 必须设置为 0。

在 Line (4) 中,清单 9 中的表达式 pos + width 必须在 while 循环中使用 offsetByCodePoints(pos,width) 替换。需要计算的量位于 width 的值中,因为第一个参数指定当 width 的值。接下来,在 Line (5) 中,表达式 pos+=width 必须使用表达式 pos=end 替换。这避免两次调用 offsetByCodePoints() 来计算相同的索引。源代码可以被进一步修改以最小化处理时间。

处理时间比较

图 1 和图 2 展示了示例 2-1、2-2 和 2-3 的处理时间。样例字符串包含相同数量的代理对和非代理对。当字符串的长度和 width 的值被更改时,样例字符串被切割 10,000 次。 图 1. 一个分段的常量宽度

图 2. 分段的常量计数

示例 2-1 和 2-3 按照长度比例增加了它们的处理时间,但 示例 2-2 按照长度的平方比例增加了处理时间。当字符串长度和 width …… 此处隐藏:2042字,全部文档内容请下载后查看。喜欢就下载吧 ……

JAVA 技术文章收集(4).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.jiaowen.net/wendang/447928.html(转载请注明文章来源)
Copyright © 2020-2025 教文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:78024566 邮箱:78024566@qq.com
苏ICP备19068818号-2
Top
× 游客快捷下载通道(下载后可以自由复制和排版)
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能出现无法下载或内容有问题,请联系客服协助您处理。
× 常见问题(客服时间:周一到周五 9:30-18:00)