问题:

StringBuffer中有delete、setLength两个方法可以快速清空字符数组。哪个效率高呢?

结论:从清空字符串角度看,两者效率都很高,比较来看,setLength效率更高

分析如下:

这两个函数都是继承自AbstractStringBuilder类。函数原型如下:  

       public AbstractStringBuilder delete(int start, int end) ;
public void setLength(int newLength) ;

delete(int start, int end)删除了start、end之间的字符,并返回新的字符串。

setLength(int newLength)重新设置了字符长度,如果newLength比原长度大,则新增的空间赋值为‘\0’。

两者用途不同,却都可以用于清空字符串。delete(0,AbstractStringBuilder.length) 与setLength(0)可以达到相同的效果。

比较其源代码之后,发现setLength(0)在清空代码时只是对长度做了 一次赋值,setLength除了对长度赋值外,还做了一次代码copy操作。多执行的代码如下:

System.arraycopy(value, start+len, value, start, count-end);

因为count = end;所以这个copy应该也不会执行。但是delete函数多做了一些判断,效率上回比setLength低一点。不过delete多出的条件判断对性能的影响是微乎其微的,通过代码测试没有明显的差异,两者在清空字符串时效率都非常高

另外,这个两个函数虽然可以将字符串清空,但并没有将资源回收,也就是说并没有达到回收资源的效果,因为AbstractStringBuilder 的字符数组仍在内存中,只不过我们人为将数组的有效长度置位了0,数组所占的资源并没有及时释放,只能等java的垃圾回收进行释放。

Jdk1.8源代码如下(jdk1.6与之类似,以上结论不变)

public AbstractStringBuilder delete(int start, int end) {

        if (start < 0)
throw new StringIndexOutOfBoundsException(start); if (end > count)
end = count; if (start > end)
throw new StringIndexOutOfBoundsException(); int len = end - start;
if (len > 0) {
System.arraycopy(value, start+len, value, start, count-end);
count -= len;
}
return this; } public void setLength(int newLength) { if (newLength < 0)
throw new StringIndexOutOfBoundsException(newLength);
ensureCapacityInternal(newLength);
if (count < newLength) {
Arrays.fill(value, count, newLength, '\0');
} count = newLength; }
    

测试代码:

package myString;
public class TestMain { public static void main(String[] args) {
testStringBufferclear();
} private static void testStringBufferclear() {
StringBuffer sbf = new StringBuffer("wwwwww");
StringBuffer sbi = new StringBuffer("wwwwww");
int count = 1000000;
long start ;
long end; StringBuffer sbftest = new StringBuffer();
for(int i = 0; i < 1000; i++)
{
sbftest.append("1234567890");
}
String str = sbftest.toString(); start = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
sbi.append(str);
sbi.setLength(0); }
end = System.currentTimeMillis();
System.out.println("StringBuffer--setLength:" + (end - start));

start = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
sbf.append(str);
sbf.delete(0, sbf.length());
}
end = System.currentTimeMillis();
System.out.println("StringBuffer--delete:" + (end - start));

start = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
sbf.append(str);
sbf = new StringBuffer("123431431");
}
end = System.currentTimeMillis();
System.out.println("StringBuffer--new StringBuffer:" + (end - start));
}
}

测试结果:

StringBuffer--setLength:674
StringBuffer--delete:689
StringBuffer--new StringBuffer:4108

StringBuffer中delete与setLength清空字符串效率比较的更多相关文章

  1. List的add方法与addAll方法的区别、StringBuffer的delete方法与deleteCharAt的区别

    List的add方法与addAll方法 区别 add add是将传入的参数作为当前List中的一个Item存储,即使你传入一个List也只会另当前的List增加1个元素 addAll addAll是传 ...

  2. 为什么 Java 8 中不再需要 StringBuilder 拼接字符串

    为什么 Java 8 中不再需要 StringBuilder 拼接字符串 来源:codeceo 发布时间:2016-12-27 阅读次数:427 0   在Java开发者中,字符串的拼接占用资源高往往 ...

  3. c++拼接字符串效率比较(+=、append、stringstream、sprintf)

    转自:http://www.cnblogs.com/james6176/p/3222671.html c++拼接字符串效率比较(+=.append.stringstream.sprintf) 最近写的 ...

  4. C#中如何正确的操作字符串?

    字符串应该是所有编程语言中使用最频繁的一种基础数据类型.如果使用不慎,我们就会为一次字符串的操作所带来的额外性能开销而付出代价.本条建议将从两个方面来探讨如何规避这类性能开销: 1. 确保尽量少的装箱 ...

  5. (四)Python中的“四大才子”(字符串、列表、字典、集合)

    前戏:在python中把数据序列分为可变(mutable)和不可变(immutable)两种 不可变:string.int.float.tuple 特点:相同对象只是占用一个内存地址,不管有多少个变量 ...

  6. String拼接字符串效率低,你知道原因吗?

    面试官Q1:请问为什么String用"+"拼接字符串效率低下,最好能从JVM角度谈谈吗? 对于这个问题,我们先来看看如下代码: public class StringTest { ...

  7. 2.StringBuffer:线程安全的可变字符串序列

    一.String.StringBuffer和StringBuilder的区别 1.String是内容不可变的,而StringBuffer和StringBuilder都是内容可变的. 2.StringB ...

  8. 3-java中String值为空字符串与null的判断方法

    java中String值为空字符串与null的判断方法 2018年01月21日 14:53:45 阅读数:1189 Java空字符串与null的区别 1.类型 null表示的是一个对象的值,而不是一个 ...

  9. 【问题】Asp.net MVC 的cshtml页面中调用JS方法传递字符串变量参数

    [问题]Asp.net MVC 的cshtml页面中调用JS方法传递字符串变量参数. [解决]直接对变量加引号,如: <button onclick="deleteProduct('@ ...

随机推荐

  1. Ubuntu的apt-get代理设置

    三种方法 -o选项 # sudo apt-get -o Acquire::http::proxy="http://127.0.0.1:8080/" update 配置文件 # vi ...

  2. 免安装方式的Python之VSCode环境配置

    概述 本文旨在介绍免安装方式,在VSCode中搭建Python(3.73)的配置环境.至于Python是什么.它能做些什么,诸如此类的介绍均不在此文中介绍,相信能看此文的人,多多少少都会有些了解. V ...

  3. 《数据结构与算法之美》 <04>链表(上):如何实现LRU缓存淘汰算法?

    今天我们来聊聊“链表(Linked list)”这个数据结构.学习链表有什么用呢?为了回答这个问题,我们先来讨论一个经典的链表应用场景,那就是 LRU 缓存淘汰算法. 缓存是一种提高数据读取性能的技术 ...

  4. c/c++编译器配置(交叉编译重要参数)、交叉编译动态库与as配置、mk初步

    gcc/g++/clang,相当于javac: 了解c/c++编译器的基本使用,能够在后续移植第三方框架进行交叉编译时,清楚的了解应该传递什么参数. clang: clang 是一个C.C++.Obj ...

  5. vue-cli3 配置全局less 、sass 变量

    之前在用vue-cli3框架的时候对于常用的less .sass 变量都是需要时就在单文件中引入文件,这样做比较麻烦.那么基于 vue-cli3 如何配置全局的less .sass 变量? <1 ...

  6. linux目录太长怎么办?分享一点小技巧

    在linux使用cd的时候,可能会遇到目录比较深的时候,这个时候总是cd一个很长的目录会很麻烦,那有没有什么比较方便的方法呢? 若是在两个目录中来回切换,这个时候可以使用cd - 这个命令,可以完成在 ...

  7. Selenium(四)使用xpath定位元素

    1.什么是xpath: 2.xpath的节点类型 3.xpath的表达式 4.开始定位 浏览器打开本地文件:   (python3.7的打开语法) 查找根节点: (绝对路径)查找子节点: 查找type ...

  8. 使用 webpack-bundle-analyzer 分析 webpack 代码库拆分块

    github:https://github.com/webpack-contrib/webpack-bundle-analyzer 1.安装: cnpm install webpack-bundle- ...

  9. mysql 5.5 编码设置为utf8 转载自:http://outofcontrol.ca/thoughts/comments/change-mysql-5.5-default-character-set-to-utf8

    Change MySQL 5.5 default character-set to UTF8 连接里是linux下的 在window下my.ini Add under [client]  the fo ...

  10. Android系统输入事件分发详解

    什么是输入事件? 我们知道,运行android系统的设备本质上是一台计算机,使用者在和计算机进行交互的时候可以抽象成简单的对计算机的输入和输出(IO).那么对于运行在计算机上的操作系统来说,操作系统在 ...