https://blog.csdn.net/u011489043/article/details/68488459

转自https://blog.csdn.net/u011489043/article/details/68488459

String 字符串常量

??StringBuffer 字符串变量(线程安全)

??StringBuilder 字符串变量(非线程安全)

??简要的说, String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象, 因为String类的声明是:public final,因此在每次对
String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String
对象,所以经常改变内容的字符串最好不要用 String,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的
GC 就会开始工作,那速度是一定会相当慢的。

??在大部分情况下 StringBuffer > String

??Java.lang.StringBuffer:线程安全的可变字符序列。一个类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。

??可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。

??StringBuffer上的主要操作是 append 和 insert
方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append
方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的位置添加字符。

??例如,如果 z 引用一个当前内容是“start”的字符串缓冲区对象,则此方法调用 z.append(“le”) 会使字符串缓冲区包含“startle”,而 z.insert(4, “ab”) 将更改字符串缓冲区,使之变为“starabtle”。

??在大部分情况下 StringBuilder > StringBuffer

??java.lang.StringBuilder:一个可变的字符序列,是5.0新增的。此类提供一个与 StringBuffer 兼容的
API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同。

??Java中StringBuilder的用法:

??String对象是不可改变的。每次使用 System.String类中的方法之一时,都要在内存中创建一个新的字符串对象,这就需要为该新对象分配新的空间。在需要对字符串执行重复修改的情况下,与创建新的 String对象相关的系统开销可能会非常昂贵。如果要修改字符串而不创建新的对象,则可以使用java.lang.StringBuilder类。例如,当在一个循环中将许多字符串连接在一起时,使用 StringBuilder类可以提升性能。

(一)通过用一个重载的构造函数方法初始化变量,可以创建 StringBuilder类的新实例,比如:

StringBuilder testStringBuilder = new StringBuilder("Hello World!");

(二)设置容量和长度:

??虽然 StringBuilder对象是动态对象,允许扩充它所封装的字符串中字符的数量,但是您可以为它可容纳的最大字符数指定一个值。此值称为该对象的容量,不应将它与当前 StringBuilder对象容纳的字符串长度混淆在一起。例如,可以创建 StringBuilder类的带有字符串“Hello”(长度为 5)的一个新实例,同时可以指定该对象的最大容量为 25。当修改 StringBuilder时,在达到容量之前,它不会为其自己重新分配空间。当达到容量时,将自动分配新的空间且容量翻倍 int newCapacity = value.length * 2 + 2;。可以使用重载的构造函数之一来指定 StringBuilder类的容量。比如:以下代码可以将 testStringBuilder对象扩充到最大25个空白

StringBuilder testStringBuilder = new StringBuilder("Hello World!",25);

(三)Append方法:

???将文本或对象的字符串表示形式添加到由当前 StringBuilder对象表示的字符串的结尾处。

(四)Insert方法:

???将字符串或对象添加到当前 StringBuilder中的指定位置。

(五)Remove方法:

???从当前 StringBuilder中移除指定数量的字符,移除过程从指定的索引处开始。

(六)Replace方法:

???可以用另一个指定的字符来替换 StringBuilder对象内的字符。

??如果程序对附加字符串的需求很频繁,不建议使用+来进行字符串的串联。可以考虑使用java.lang.StringBuilder 类使用这个类所产生的对象默认会有16个字符的容量(capacity),您也可以自行指定初始容量。如果附加的字符超出可容纳的长度,则StringBuilder 对象会自动增加容量以容纳被附加的字符。如果有频繁作字符串附加的需求,使用StringBuilder 类能使效率大大提高

??见下面测试案例:

public class testStringBuilder {

    public static void main(String[] args) {
        String text = "";

        long beginTime = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++)
            text = text + i;
        long endTime = System.currentTimeMillis();
        System.out.println("普通字符串直接相加的执行时间:" + (endTime - beginTime));

        StringBuffer sbf = new StringBuffer();
        beginTime = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++)
            sbf.append(String.valueOf(i));
        endTime = System.currentTimeMillis();
        System.out.println("使用StringBuffer的append()方法的执行时间:"+ (endTime - beginTime));

        StringBuilder sb = new StringBuilder();
        beginTime = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++)
            sb.append(String.valueOf(i));
        endTime = System.currentTimeMillis();
        System.out.println("使用StringBuilder的append()方法的执行时间:"+ (endTime - beginTime));
    }
}

??输出结果:

??普通字符串直接相加的执行时间:261

??使用StringBuffer的append()方法的执行时间:3

??使用StringBuilder的append()方法的执行时间:2

补充:Java中为什么StringBuilder比StringBuffer快?

??首先我们看一下源码:

??java.lang.StringBuilder

public StringBuilder append(String str) {
        super.append(str);
        return this;
    }

??java.lang.StringBuffer

public synchronized StringBuffer append(String str) {
        super.append(str);
        return this;
    }

??可以看到,StringBuffer类的append()方法,都被synchronized所修饰,这就是我们的主角。

??synchronized关键字是做什么的呢?在多线程中非常常见,根据用法不同,可以给方法、代码块或对象加锁。以此处为例,当多个线程访问加锁的方法时,每次只有一个线程获得锁,其他线程必须等待该线程释放锁(一般是执行完这个方法),再由下一个线程获得锁,才允许执行该方法。加锁会带来性能上的损耗(毕竟多执行了一些操作,还包括锁等待时的线程阻塞)。

??为什么StringBuffer要加锁?StringBuffer就是为了多线程而设计的,这样可以防止多个线程同时操作同一个对象,也就是线程安全。而如果使用多线程操作StringBuilder对象,则无法保证每次append进去的字符串保持原样(随线程数量和数据量增大,出现错乱的概率也越大,跟线程切换有关)。

??综上所述,Stringbuilder要比Stringbuffer快。

原文地址:https://www.cnblogs.com/lijingran/p/8979495.html

时间: 2024-10-08 17:27:18

https://blog.csdn.net/u011489043/article/details/68488459的相关文章

如何相互转换逗号分隔的字符串和List --https://blog.csdn.net/yywusuoweile/article/details/50315377

如何相互转换逗号分隔的字符串和List ---https://blog.csdn.net/yywusuoweile/article/details/50315377 方法 2: 利用Guava的Joiner [java] view plain copy List<String> list = new ArrayList<String>(); list.add("a"); list.add("b"); list.add("c"

py3 web.py转https://blog.csdn.net/weixin_42024288/article/details/80364441

https://blog.csdn.net/weixin_42024288/article/details/80364441 1.安装webpy模块: pip install web.py==0.40.dev 另外将: C:\Python34\Lib\site-packages\web.py-0.40.dev0-py3.4.egg\web\template.py 中约1022行return Template(open(path).read(), filename=path, **self._ke

Consul+upsync+Nginx实现动态负载均衡 摘自https://blog.csdn.net/qq_29247945/article/details/80787014

传统感念:每次修改完nginx配置文件,要重启nginx 动态感念:每次修改完nginx配置信息,不需要重启,nginx实时读取配置信息. Nginx: 反向代理和负载均衡 Consul:是用go编写(谷歌),实现对动态负载均衡注册与发现功能 SpringCloud支持  Zookeeper.Eureka.Consul服务注册与发现. 服务注册:服务实现者可以通过HTTP API或DNS方式,将服务注册到Consul. 服务发现:服务消费者可以通过HTTP API或DNS方式,从Consul获取

操作系统---栈区与堆区 转自:https://blog.csdn.net/amcp9/article/details/79597481

当一个程序运行时,其RAM存储方式是按照一定的区域划分的,以C为例 内存中的栈区处于相对较高的地址向较低的地址拓展,由操作系统决定的最高地址,所以它是一块连续的内存空间. 栈中分配局部变量空间,堆区是低地址向高地址拓展,用于分配程序员申请的内存空间.另外还有静态区是分配静态变量,全局变量空间的:只读区是分配常量和程序代码空间的:以及其他一些分区. 栈: 栈是为执行线程留出的内存空间.当函数被调用的时候,栈顶为局部变量和一些 bookkeeping 数据预留块.当函数执行完毕,块就没有用了,可能在

https://blog.csdn.net/doegoo/article/details/50749817

因为使用DiscuzX3.2进行系统的整合后,因为只是想在原J2EE的系统上增加论坛功能,而且J2EE中已经有一套用户的注册认证的体系,所以不需要在Discuz的系统中去注册以及登录功能,而是通过在J2EE进行注册和登录使用单点登录的方式来完成论坛的注册与登录,这样使两个系统形成了一个整体.具体关于通过J2EE登录就完成论坛登录的单点登录过程请参见<J2EE与DiscuzX3.2的UCenter实现单点登录>,这里只是描述当完成以上功能过后,如何禁止,用户直接在Discuz论坛注册以及登录.

转-java编译时error: illegal character &#39;\ufeff&#39; 的解决办法-https://blog.csdn.net/t518vs20s/article/details/80833061

原文链接:https://blog.csdn.net/shixing_11/article/details/6976900 最近开发人员通过SVN提交了xxx.java文件,因发布时该包有问题需要回退,故SCM将该xxx.java文件用editplus打开删除了新添的一行,删除后重新编译打包,却报了如下异常: java:[1,0] illegal character: \65279 表面看着该文件确实没错,看不出来问题,后来从SVN上更新下代码以后,发现本地也不报错,后来通过Eclipse查看了

https://blog.csdn.net/the_liang/article/details/82708907

转自:https://blog.csdn.net/the_liang/article/details/82708907 Xmanager Power Suit 6.0.0109 最新版注册激活,长期更新以下方法基本上可以对最近版本适用,也就是说不需要我更新文章,你也可以通过以下方法尝试激活最新的版本!操作步骤 Xmanger Power Suit 官方 其实有两种 .exe 文件,一个是用于试用的,在注册的时候不能直接输入密钥.而另一个是为注册用户提供的 .exe 文件,在注册的时候可以输入密钥

https://blog.csdn.net/wang926454/article/details/82971442

https://blog.csdn.net/wang926454/article/details/82971442 https://github.com/dolyw/VueStudy 原文地址:https://www.cnblogs.com/leiqun123/p/12036600.html

每次换电脑 或者重装系统的时候有点麻烦转自别人的https://blog.csdn.net/u014722022/article/details/100170664

记录一下自己安装过程遇到的问题,也希望对大家有用~ 1.下载(官方推荐的是下载安装版本,但是解压版更便捷),下载地址: 2.解压,我们需要增加一步操作: (1)创建一个名为my.ini的文件,补充:之前建了data文件夹,但是后续安装报错,引以为戒: 3.修改my.ini文件: [mysql] # 设置mysql客户端默认字符集 default-character-set=utf8 [mysqld] # 设置3306端口 port = 3306 # 设置mysql的安装目录 basedir =