[置顶] String StringBuffer StringBuilder的区别剖析
这是一道很常见的面试题目,至少我遇到过String/StringBuffer/StringBuilder的区别:String是不可变的对象(final)类型,每一次对String对象的更改均是生成一个新的String对象,原有的对象不会改变,相比之下StringBuffer与StringBuilder均是可更改的对象,效率要大于String,两者之间的区别在于StringBuffer适用于多线程,是线程安全的,而StringBuiler是JDK5.0后出来的,专门针对单线程,效率上要高于StringBuffer。
String测试的源代码:
//生成一个字符串对象
String str="abc";
//让两个tmp指向同一个字符串
String tmp=str;
//对字符串进行重新赋值,如果str是可以更改的,那么最终的结果就是tmp与str的值还是一样的
str="abc"+str;
//将结果打印出来
System.out.println(str);//test
System.out.println(tmp);//abc
//时间测试,待会与后面结果对比
long start=System.currentTimeMillis();
for(int i=0;i<1000000;i++)
str="a"+str;
//平均时间会运行好久好久的,真的,你可以试试,有几分钟
System.out.println(System.currentTimeMillis()-start);
上面的代码很显然了吧,如果String是可变对象的话,那么str与tmp的结果应该是一样的,因为指向了同一片空间,但最后结果不一样,是因为String指向的空间是一个final类型,不可更改的,执行str=”test”,实际上是又重新申请了空间存放test,然后str指向了”test”这片空间,而tmp不变,最后的时间测试中,由于每次都是由str+”a”构造出一个新的对象,然后将str指向这个新的对象,期间str原来指向的空间会由GC回收,因此会很费时的。
看看String类实现的部份源码
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence
{
/** 存放字符串的空间,看看前面的final,应该就明白了吧,修饰的内容是不可更改的*/
private final char value[]; /**偏移位置,第一个字符*/
private final int offset; /**字符个数*/
private final int count;
你也会发现,里面用来存储字符串的是一个char型的数组value,看看char的前面的那个final,应该明白了吧:)
StringBuffer的测试源代码:
//生成一个StringBuffer对象,并在里面存放abc
StringBuffer str=new StringBuffer("abc");
//tmp也指向这个StringBuffer对象
StringBuffer tmp=str;
//对字符串进行重新赋值,如果str是可以更改的,那么最终的结果就是tmp与str的值还是一样的
str=str.append("abc");
//将结果打印出来
System.out.println(str);//abcabc
System.out.println(tmp);//abcabc
//时间测试,待会与后面结果对比
long start=System.currentTimeMillis();
for(int i=0;i<1000000;i++)
str=str.append("a");
//平均时间在63ms左右
System.out.println(System.currentTimeMillis()-start);
上面的代码也是很显然的吗,由于操作的始终是同一个对象,同一片内存空间,因此tmp与str的值是一样的,在测试时间时,由于避免了内存的释放与回收(不是绝对的避免,当内存不足以存放数据时,又重新分配一片大点的空间,总的来说就是减少的内存的释放与回收),因此时间大大减少,效率提高了。
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{ /** use serialVersionUID from JDK 1.0.2 for interoperability */
static final long serialVersionUID = 3388685877147921107L; /**
* 可以看出会有16B的默认空间
*/
public StringBuffer() {
super(16);
}
从这里可以看出,如果什么都不存放的话,StringBuffer会有16字节的默认空间
看看StringBuffer的父类,更清楚:)
abstract class AbstractStringBuilder implements Appendable, CharSequence {
/**
*这个value就是用来存放字符串的,默认情况下就是16B的空间,没有final吧:)
*/
char value[];
看了这些,你也应该知道String与StringBuffer的区别,还有一点就是StringBuffer是线程安全的,体现在哪呢,看看源代码吧:)
public synchronized int length() {
return count;
}
public synchronized int capacity() {
return value.length;
}
public synchronized void ensureCapacity(int minimumCapacity) {
if (minimumCapacity > value.length) {
expandCapacity(minimumCapacity);
}
}
上面只是部份方法,你可以看到的是大部份的方法都含有一个synchronized关键字,这个关键字的作用就是用来进行线程同步的,因此是多线程安全的。
StringBuilder的测试源代码:
//生成一个StringBuilder对象,并在里面存放abc
StringBuilder str=new StringBuilder("abc");
//tmp也指向这个StringBuffer对象
StringBuilder tmp=str;
//对字符串进行重新赋值,如果str是可以更改的,那么最终的结果就是tmp与str的值还是一样的
str=str.append("abc");
//将结果打印出来
System.out.println(str);//abcabc
System.out.println(tmp);//abcabc
//时间测试,待会与后面结果对比
long start=System.currentTimeMillis();
for(int i=0;i<1000000;i++)
str=str.append("a");
//平均时间在36左右
System.out.println(System.currentTimeMillis()-start);
上面的代码也是类似的,说明了StringBuilder与StringBuffer类似,但比StringBuffer的效率更改,这是为什么呢,看看源代码就知道了:)
源代码中StringBuffer与StringBuilder继承自同一个父类,代码极奇相似,只是StringBuilder各个函数少了synchonized关键字,这也就说明了StringBuilder不是线程安全的,即然有了synchronized关键字,那么代码每次运行的时候均需要锁住该对象,以避免其他对象调用该方法,不管是单线程还是多线程,因此这需要一定的开销,因此StringBuiler的效率要高于StringBuffer:)
[置顶] String StringBuffer StringBuilder的区别剖析的更多相关文章
- String,StringBuffer,StringBuilder的区别
public static void main(String[] args) { String str = new String("hello...."); StringBuffe ...
- String,StringBuffer,StringBuilder的区别及其源码分析
String,StringBuffer,StringBuilder的区别这个问题几乎是面试必问的题,这里做了一些总结: 1.先来分析一下这三个类之间的关系 乍一看它们都是用于处理字符串的java类,而 ...
- Question 20171115 String&&StringBuffer&&StringBuilder的区别与联系?
Question 20171114 String&&StringBuffer&&StringBuilder的区别和联系 创建成功的String对象,其长度是固定的,内容 ...
- java中 String StringBuffer StringBuilder的区别
* String类是不可变类,只要对String进行修改,都会导致新的对象生成. * StringBuffer和StringBuilder都是可变类,任何对字符串的改变都不会产生新的对象. 在实际使用 ...
- 深入理解String, StringBuffer, StringBuilder的区别(基于JDK1.8)
String.StringBuffer.StringBuilder都是JAVA中常用的字符串操作类,对于他们的区别大家也都能耳熟能详,但底层到底是怎样实现的呢?今天就再深入分析下这三种字符串操作的区别 ...
- Android/Java 中的 String, StringBuffer, StringBuilder的区别和使用
Android 中的 String, StringBuffer 和 StringBuilder 是移动手机开发中经常使用到的字符串类.做为基础知识是必须要理解的,这里做一些总结. A.区别 可以从以下 ...
- 在JAVA中,String,Stringbuffer,StringBuilder 的区别
首先是,String,StringBuffer的区别 两者的主要却别有两方面,第一是线程安全方面,第二是效率方面 线程安全方面: String 不是线程安全的,这意味着在不同线程共享一个String ...
- String,StringBuffer,StringBuilder三者区别
String:每次改变,String都会重新构造,内存指针都会改变 StringBuffer:主要用在全局变量中 StringBuilder:在线程内完成字符拼接,因为线程是不安全的,所以完成后可以丢 ...
- 从源码看String,StringBuffer,StringBuilder的区别
前言 看了一篇文章,大概是讲面试中的java基础的,有如题这么个面试题.我又翻了一些文章看了下,然后去看源码.看一下源码大概能更加了解一些. String String类是final的,表示不可被继承 ...
随机推荐
- 第 9 章 模板方法模式【Template Method Pattern】
以下内容出自:<<24种设计模式介绍与6大设计原则>> 周三,9:00,我刚刚坐到位置,打开电脑准备开始干活. “小三,小三,叫一下其它同事,到会议室,开会”老大跑过来吼,带着 ...
- BZOJ 1629: [Usaco2007 Demo]Cow Acrobats
Description Farmer John's N (1 <= N <= 50,000) cows (numbered 1..N) are planning to run away a ...
- 【网络流24题】No. 13 星际转移问题 (网络判定 最大流)
[题意] 由于人类对自然资源的消耗, 人们意识到大约在 2300 年之后, 地球就不能再居住了.于是在月球上建立了新的绿地,以便在需要时移民. 令人意想不到的是, 2177 年冬由于未知的原因, 地球 ...
- ANDROID_MARS学习笔记_S04_001_OAUTH获取request_token
一.代码 1.xml(1)main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLay ...
- 解读30个提高Web程序执行效率的好经验
其实微博是个好东西,关注一些技术博主之后,你不用再逛好多论坛了,因为一些很好的文章微博会告诉你,最近看到酷勤网推荐的一篇文章<30个提高Web程序执行效率的好经验>,文章写得不错,提到一些 ...
- POJ_3104_Drying_(二分,最小化最大值)
描述 http://poj.org/problem?id=3104 n件衣服,第i件衣服里面有水a[i],自然风干每分钟干1个水,用吹风机每分钟干k个水,但是同时只能对一件衣服使用吹风机,求干完所有衣 ...
- Nginx 安装成 Windows 服务
Nginx 安装成Windows 服务方法,具体方法如下 1. 下载nginx windows版本 http://www.nginx.org 2. 下载微软的2个工具: instsrv.exe.srv ...
- HDU 5938 Four Operations 【贪心】(2016年中国大学生程序设计竞赛(杭州))
Four Operations Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...
- Java之Arrays.asList陷阱
Java.Util.Arrays可以将数组转换为List,具体的定义如下: @SafeVarargs public static <T> List<T> asList(T... ...
- 根据地址查询经纬度.html
<html xmlns="http://www.w3.org/1999/xhtml"><head> <title>根据地址查询经纬度</t ...