您不应使用deleteCharAt方法。
正如鲍里斯指出的那样,deleteCharAt方法每次都会复制该数组。Java 5中执行此操作的代码如下所示:
public AbstractStringBuilder deleteCharAt(int index) { if ((index < 0) || (index >= count)) throw new StringIndexOutOfBoundsException(index); System.arraycopy(value, index+1, value, index, count-index-1); count--; return this;}当然,仅凭猜测还不足以选择一种优化方法而不是另一种优化方法,因此我决定在此线程中计时三种方法:原始方法,删除方法和子字符串方法。
这是我为原始代码测试的代码:
public static String trimOriginal(StringBuilder sb) { return sb.toString().trim();}删除方法:
public static String trimDelete(StringBuilder sb) { while (sb.length() > 0 && Character.isWhitespace(sb.charAt(0))) { sb.deleteCharAt(0); } while (sb.length() > 0 && Character.isWhitespace(sb.charAt(sb.length() - 1))) { sb.deleteCharAt(sb.length() - 1); } return sb.toString();}和子串方法:
public static String trimSubstring(StringBuilder sb) { int first, last; for (first=0; first<sb.length(); first++) if (!Character.isWhitespace(sb.charAt(first))) break; for (last=sb.length(); last>first; last--) if (!Character.isWhitespace(sb.charAt(last-1))) break; return sb.substring(first, last);}我执行了100次测试,每次生成带有一万个尾随和前导空格的百万字符StringBuffer。测试本身是非常基础的,但是可以很好地了解这些方法需要花费多长时间。
这是计时三种方法的代码:
public static void main(String[] args) { long originalTime = 0; long deleteTime = 0; long substringTime = 0; for (int i=0; i<100; i++) { StringBuilder sb1 = new StringBuilder(); StringBuilder sb2 = new StringBuilder(); StringBuilder sb3 = new StringBuilder(); for (int j=0; j<10000; j++) { sb1.append(" "); sb2.append(" "); sb3.append(" "); } for (int j=0; j<980000; j++) { sb1.append("a"); sb2.append("a"); sb3.append("a"); } for (int j=0; j<10000; j++) { sb1.append(" "); sb2.append(" "); sb3.append(" "); } long timer1 = System.currentTimeMillis(); trimOriginal(sb1); originalTime += System.currentTimeMillis() - timer1; long timer2 = System.currentTimeMillis(); trimDelete(sb2); deleteTime += System.currentTimeMillis() - timer2; long timer3 = System.currentTimeMillis(); trimSubstring(sb3); substringTime += System.currentTimeMillis() - timer3; } System.out.println("original: " + originalTime + " ms"); System.out.println("delete: " + deleteTime + " ms"); System.out.println("substring: " + substringTime + " ms");}我得到以下输出:
original: 176 msdelete: 179242 mssubstring: 154 ms
如我们所见,与原始的“两个字符串”方法相比,子字符串方法提供了非常轻微的优化。但是,删除方法非常慢,应该避免。
因此,回答您的问题:您可以按照问题中的建议很好地调整StringBuilder。substring方法提供的非常轻微的优化可能无法证明多余的代码是正确的。



