Java中的String、StringBuilder,StringBuffer简析
来源:互联网 发布:已连接,但无法访问网络 编辑:程序博客网 时间:2024/06/05 07:19
JAVA中用于处理字符串常用的有三个类:java.lang.String、java.lang.StringBuffer、java.lang.StringBuilder,这三者的共同之处都是final类,不允许被继承,这主要是从性能和安全性上考虑的,因为这几个类都是经常被使用着的,且考虑到防止其中的参数被修改影响到其它的应用。StringBuffer与StringBuilder两个基本上差不多,只是StringBuffer是线程安全,可以不需要额外的同步用于多线程中;StringBuilder是非同步,运行于多线程中就需要使用着单独同步处理,但是速度就比StringBuffer快多了;二者之间的共同点都可以通过append、insert进行字符串的操作。
String实现了三个接口:Serializable、Comparable<String>、CharSequence,而StringBuffer及StringBuilder只实现了两个接口Serializable、CharSequence,相比之下String的实例可以通过compareTo方法进行比较,而其它两个就不可以。
StringBuffer线程安全的可变字符序列。只要发生有关源序列(如在源序列中添加或插入)的操作,该类就只在执行此操作的字符串缓冲区上而不是在源上实现同步。从 JDK 5 开始,为该类补充了一个单个线程使用的等价类,即 StringBuilder。与该类相比,通常应该优先使用 StringBuilder 类,因为它支持所有相同的操作,但由于它不执行同步,所以速度更快。
StringBuilder一个可变的字符序列。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。
详细出处参考http://wenku.baidu.com/view/5d696e3e5727a5e9856a6123.html
1. String 类,String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间。 String a = "a"; //假设a指向地址0x0001 a = "b";//重新赋值后a指向地址0x0002,但0x0001地址中保存的"a"依旧存在,但已经不再是a所指向的,a 已经指向了其它地址。 因此String的操作都是改变赋值地址而不是改变值操作。
2. StringBuffer是可变类,和线程安全的字符串操作类,任何对它指向的字符串的操作都不会产生新的对象。 每个StringBuffer对象都有一定的缓冲区容量,当字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,会自动增加容量。
StringBuffer buf=new StringBuffer(); //分配长16字节的字符缓冲区 StringBuffer buf=new StringBuffer(512); //分配长512字节的字符缓冲区 StringBuffer buf=new StringBuffer("this is a test")//在缓冲区中存放了字符串,并在后面预留了16字节的空缓冲区。
3.StringBuilder,StringBuffer和StringBuilder类功能基本相似,主要区别在于StringBuffer类的方法是多线程、安全的,而StringBuilder不是线程安全的,相比而言,StringBuilder类会略微快一点。对于经常要改变值的字符串应该使用StringBuffer和StringBuilder类。
4.线程安全: StringBuffer 线程安全; StringBuilder 线程不安全
5.速度:一般情况下,速度从快到慢:StringBuilder>StringBuffer>String,这种比较是相对的,不是绝对的。
6.总结:(1)如果要操作少量的数据用String (2)单线程操作字符串缓冲区下操作大量数据用StringBuilder (3)多线程操作字符串缓冲区下操作大量数据StringBuffer
详细出处参考:http://www.jb51.net/article/33398.htm
来看看 StringBuffer类源码定义:
public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence{ public StringBuffer() { super(16); } public StringBuffer(int capacity) { super(capacity); } ...
然后,我们打开 StringBuilder源码定义:
public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence{ public StringBuilder() { super(16); } public StringBuilder(int capacity) { super(capacity); } ...
我们发现两者都继承了AbstractStringBuilder抽象类。且构造方法都调用父类实现。
我们接着看两者append方法实现,先看StringBuffer的:
public synchronized StringBuffer append(Object obj) { super.append(String.valueOf(obj)); return this; } public synchronized StringBuffer append(String str) { super.append(str); return this; } //...
再看StringBuilder的:
public StringBuilder append(Object obj) { return append(String.valueOf(obj)); } public StringBuilder append(String str) { super.append(str); return this; } //...
对比上面两段源码 我们发现 StirngBuffer 和StringBuilder的 append实现都是调用父类实现的。唯一不同的是 StringBuffer是线程安全的,方法中多了synchronized ,而StringBuilder 是非线程安全的。
我们再看一下append的实现:
public AbstractStringBuilder append(Object obj) { return append(String.valueOf(obj)); } public AbstractStringBuilder append(String str) { //对于str==null的 if (str == null) str = "null"; int len = str.length(); if (len == 0) return this; //新的字符串长度 int newCount = count + len; if (newCount > value.length) //当新的字符串长度比原先数组长度大时,需要对char 数组扩容。 expandCapacity(newCount); //将新添的数据追加到char类型数组中。 str.getChars(0, len, value, count); count = newCount; return this; } //数组扩容 void expandCapacity(int minimumCapacity) { //先扩容成 (原先的长度+1)*2 int newCapacity = (value.length + 1) * 2; //判断newCapacity值是否满足要求 //如果新的长度还是不够,则直接取值 minimumCapacity if (newCapacity < 0) { newCapacity = Integer.MAX_VALUE; } else if (minimumCapacity > newCapacity) { newCapacity = minimumCapacity; } char newValue[] = new char[newCapacity]; //将原先的数据拷贝到新的char 数组中。 System.arraycopy(value, 0, newValue, 0, count); value = newValue; } public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) { if (srcBegin < 0) { throw new StringIndexOutOfBoundsException(srcBegin); } if (srcEnd > count) { throw new StringIndexOutOfBoundsException(srcEnd); } if (srcBegin > srcEnd) { throw new StringIndexOutOfBoundsException(srcEnd - srcBegin); } System.arraycopy(value, offset + srcBegin, dst, dstBegin, srcEnd - srcBegin); }
- Java中的String、StringBuilder,StringBuffer简析
- java中的String,StringBuffer,StringBuilder
- java中的String,StringBuilder,StringBuffer
- java中的String StringBuilder StringBuffer
- java中的String,StringBuffer,StringBuilder
- Java中的String、StringBuilder、StringBuffer
- Java中的String,StringBuffer,StringBuilder
- java中的String、StringBuffer、StringBuilder
- Java中的字符串 String, StringBuffer和StringBuilder
- 重温java中的String,StringBuffer,StringBuilder类
- Java中的String、StringBuffer和StringBuilder
- 探秘Java中的String、StringBuilder以及StringBuffer
- 探秘Java中的String、StringBuilder以及StringBuffer
- java中的String,StringBuffer和StringBuilder浅谈
- 探秘Java中的String、StringBuilder以及StringBuffer
- 探秘Java中的String、StringBuilder以及StringBuffer
- Java中的String、StringBuilder、StringBuffer对比
- Java中的String,StringBuffer,StringBuilder的区别
- ExecuteReader的用法
- 快速排序
- sizeof()和strlen()的检测与对比
- JVM参数调优
- HDU 1010 Tempter of the Bone
- Java中的String、StringBuilder,StringBuffer简析
- uva 10245 - The Closest Pair Problem(暴力剪枝)
- UVA 10194 Football (aka Soccer) 足球成绩统计 检索+模拟
- b3log的ArticleSender不是往本地数据库存文章的
- HDU 2097 Sky数
- HDU 2098 分拆素数和
- Oracle优化器选择
- HDU 2096 小明A+B
- 用户级线程与内核级线程