String,StringBuilder 以及 StringBuffer 这三个类的关系与区别一直是 Java 的经典问题,这次就来讲一下关于这三个类的一些知识

一. 简单对比

  • String : 字符常量
  • StringBuilder : 字符变量
  • StringBuffer : 字符变量

String 属于常量类型,被声明为 final class,所有的属性也都是 final 类型,因此 String 对象一旦创建,便不可更改;

StringBuilder / StringBuffer 两个类属于变量类型,是可以更改的,它们都是为了解决字符串由于拼接产生太多中间对象的问题而提供的类。

  • 运行速度 StringBuilder > StringBuffer > String

  • 线程安全: StringBuffer

  • 非线程安全 : StringBuilder

StringBuilder 在本质上和 StringBuffer 没有太大区别,但是由于 StringBuilder 去掉了 StringBuffer 拥有的线程安全部分,因此有效减少了开销。因此,StringBuilder 是大部分情况下字符串拼接操作的首选

二. String 处理字符串

例一:

String s = "abcd";
s = s + "fgh";

很多人作这样的字符串处理的时候会误认为 String 类型是可变的。

但其实 JVM 处理这段代码的过程是这样的:首先创建 s 对象,赋值“abcd” ,然后处理第二行代码时,再创建一个 s 对象,赋值 “abcdfgh”,然后将第一个 s 对象垃圾回收。

所以相当于第一个 s 没更改过,第二个 s 是新的对象

例二:

String str = “This is only a” + “simple” + “test”;

这段代码相当于 String str = “This is only a simple test”;

例三:

String str2 = "This is only a";
String str3 = "simple";
String str4 = "test";
String str1 = str2 +str3 + str4;

这段代码同样会按照例一的过程来处理

三. StringBuilder / StringBuffer 构造特性

这两个对象在构造的过程中,首先按照默认大小申请一个字符数组(char[]), 默认容量为 16 个字符,但如果超出,会使用 Arrays.copyOf() 成倍扩容 16,32,64, 128...,当然这样会影响性能,因此可以在创建对象时按照需要自定义其容量

源代码:
//默认 16 个字符
public StringBuilder() {
super(16);
}
//构造函数定义容量
public StringBuilder(int capacity) {
super(capacity);
}

四. String 与 StringBuilder 处理字符串拼接对比

我们都知道,进行字符串拼接操作时推荐使用 StringBuilder,但是是不是什么时候都推荐使用 StringBuilder 来代替 String 进行字符串拼接?显然不是的。

例一:

String str = "123";
String str1 = str + "456";
String str2 = new StringBuilder().append(str).append("def").toString();

在这种情况下,两种处理方式效率差别不大

JDK 8 中, String 的字符串拼接操作会被编译器自动转换为 StringBuilder 并调用 append 方法,由于这样的优化方案,使得两个类在这种情况下的处理效率差别不大;而在 JDK 9 中,为了更加统一字符串操作优化,提供了 StringConcatFactory,作为一个统一的入口,更加优化了字符串拼接操作。

例二:

String str = "";
for (int i = 0; i < 1000; i++) {
str += "12345";
} StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < 1000; i++) {
stringBuilder.append("12345");
}

这种情况下,StringBuilder 更快

在循环中,每执行一次 “+”,都会创建一个 String 对象,因此会有大量对象创建和回收的消耗。

简单来说,在循环中对同一个字符串对象做字符串拼接,优先选择 StringBuilder

例三

String str1 = "123" + "456" + "789";

String str2 = new StringBuilder("123").append("456").append("789").toString();

这种情况下,String 更快

我们都知道 String str1 = "123" + "456" + "789"; 其实是等同于 String str1 = "123456789";的,而 StringBuilder 反而需要多次调用 append 方法。

你必须搞清楚的String,StringBuilder,StringBuffer的更多相关文章

  1. 深入源码剖析String,StringBuilder,StringBuffer

    [String,StringBuffer,StringBulider] 深入源码剖析String,StringBuilder,StringBuffer [作者:高瑞林] [博客地址]http://ww ...

  2. String, StringBuilder, StringBuffer问题

    1. 区别 String为字符串常量,而StringBuilder和StringBuffer都是字符串变量,其中StringBuilder线程非安全,StringBuffer线程安全. 每次对 Str ...

  3. String StringBuilder StringBuffer区别

    String StringBuilder StringBuffer String类是final类,不可以被继承,且它的成员方法也是final方法,当一个字符串对象进行操作操作时,任何的改变不会影响到这 ...

  4. difference among String,StringBuilder,StringBuffer

    difference among String,StringBuilder,StringBuffer String常用构造函数 String(byte[] bytes) String(byte[] b ...

  5. JDK源码分析系列---String,StringBuilder,StringBuffer

    JDK源码分析系列---String,StringBuilder,StringBuffer 1.String public final class String implements java.io. ...

  6. java中String StringBuilder StringBuffer比较和效率(性能)测试

    string stringbuilder stringbuffer三者的区别 从JDK源码看,String.StringBuilder.StringBuffer都是存放在char[] 数组字符串. 简 ...

  7. String StringBuilder StringBuffer 对比 总结得非常好

    转自:http://www.iteye.com/topic/522167 作者:每次上网冲杯Java时,都能看到关于String无休无止的争论.还是觉得有必要让这个讨厌又很可爱的String美眉,赤裸 ...

  8. (转)String StringBuilder StringBuffer 对比 总结得非常好

    来源:http://blog.csdn.net/clam_clam/article/details/6831345 转自:http://www.iteye.com/topic/522167 作者:每次 ...

  9. string,stringbuilder,stringbuffer用法

    总结:1.如果要操作少量的数据用 = String   ==================================>字符串常量2.单线程操作字符串缓冲区 下操作大量数据 = Strin ...

  10. java中string stringbuilder stringbuffer 的区别

    1. String 类 String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间. String a = "a&qu ...

随机推荐

  1. 命令行使用Eclipse的debug签名失败“找不到 xx.keystore证书链”

    1.debug签名位置 2.查看debug.keystore具体信息 3.使用命令行签名 注意:debug签名password为android 4.出错原因是签名的别名写错,应为androiddebu ...

  2. winform设置超时时间

    ); //设置超时时间 var completedTask = await Task.WhenAny(new Task(async () => { );//执行的方法示例这里用延迟代替 }), ...

  3. Android 怎样实现 焦点图的 无线循环滑动的状态?

    參考网址:http://my.oschina.net/xsk/blog/119167 总体的架构:ViewPgaer 中直接嵌套  IamgeView 方案一:  重写Viewpager 这样有局限性 ...

  4. java封装AES加密算法

    在实际coding中会常常遇到往数据库存入密码时加密.URL传參时的加密.由此简单封装了下java中的AES加密算法. 0.import类 import java.security.SecureRan ...

  5. 0x52 背包

    还行 前面的题没啥意思 完全背包一个很难写的题poj1015 Jury Compromise poj1742 多重背包啊,开始写了二进制拆分TLE了,由于是判是否可以组成,那么可以用一个贪心的思想,顺 ...

  6. DNS隧道工具使用 不过其网络传输速度限制较大

    DNS隧道工具使用 http://www.freebuf.com/sectool/112076.html http://netsec.ccert.edu.cn/zhengming/2011/11/01 ...

  7. 使用autofac在mvc5下依赖注入

    把遇到的问题汇总一下: 一.安装mvc5版本 命令:pm> Install-Package Autofac 结果安装的Autofac.Integration.Mvc(版本为4.0),所引用的依赖 ...

  8. C++程序开发的基本过程

    前两天说去一家小公司实习,被他们的一个技术员工的一个问题问到了,问的我当时都没有反应过来,回来后突然发现这个问题我会啊 ,只是当时没想到这么浅显.现在总结下: C++程序开发的基本过程: 1)编辑 开 ...

  9. JavaScriptResult

  10. python爬虫:读取PDF

    下面的代码可以实现用python读取PDF,包括读取本地和网络上的PDF. pdfminer下载地址:https://pypi.python.org/packages/source/p/pdfmine ...