java基础知识—String、StringBuffer和StringBuilder
2015-07-18 14:06
806 查看
本博文主要是介绍一下String、StringBuffer和StringBuilder之间的区别和联系。
注意:String、StringBuffer、StringBuilder都是final类型的,这意味着它们是不能被其它类继承的(我哥们去阿里面试的时候被问过)
由以上源码定义我们可以得到三者之间的关系图如下所示:
可以发现三者都实现了CharSequence接口,CharSequence其实也就是定义了字符串操作的接口,这个接口包含length(), charAt(int index),
subSequence(int start, int end)这几个API接口。而StringBuilder和StringBuffer都继承自AbstractStringBuilder类。
2.2StringBuilder常见构造函数
下面我们再从StringBuilder中的append函数看看他具体是怎么做的(以 append(String str) 为例看看)。
int newCount = count + len;
if (newCount > value.length) {
expandCapacity(newCount);
}
//getChars将字符串复制到指定的位置
str.getChars(0, len, value, count);
count = newCount;
return this;
}
2.3 StringBuffer构造函数
3.比较下三者之间的区别:
3.1StringBuffer和StringBuilder之间的区别和联系。
StringBuilder 和 StringBuffer都是可变的字符序列。它们都继承于AbstractStringBuilder,实现了CharSequence接口;StringBuilder是非线程安全的,而StringBuffer是线程安全的,但是很明显加上线程控制会拖慢程序运行的速度,所以如果不需要线程控制,那么最好就用StringBuilder。
3.2 String和StringBuffer、StringBuilder之间的区别。
StringBuffer和StringBuilder对象的内容可以修改;而String对象一旦产生后就不可以被修改,重新赋值其实是两个对象。StringBuffer(StringBuilder)的内部实现方式和String不同,StringBuffer在进行字符串处理时,不生成新的对象,在内存使用上要优于String类。所以在实际使用时,如果经常需要对一个字符串进行修改,例如插入、删除等操作,使用StringBuffer要更加适合一些。StringBuffer对象的append效率要高于String对象的"+"连接操作。
参考:
/article/4763105.html
1、从类的定义看StringBuffer、StringBuilder、String的关系
首先来看一下源码中这几个类的定义如下://CharSequence定义 public interface CharSequence //StringBuffer定义 public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence //StringBuilder定义 public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence //String定义 public final class String implements java.io.Serializable, Comparable<String>, CharSequence
注意:String、StringBuffer、StringBuilder都是final类型的,这意味着它们是不能被其它类继承的(我哥们去阿里面试的时候被问过)
由以上源码定义我们可以得到三者之间的关系图如下所示:
可以发现三者都实现了CharSequence接口,CharSequence其实也就是定义了字符串操作的接口,这个接口包含length(), charAt(int index),
subSequence(int start, int end)这几个API接口。而StringBuilder和StringBuffer都继承自AbstractStringBuilder类。
2、从构造函数到具体的字符串拼接操作看看String、StringBuffer、StringBuilder的区别
2.1String的构造函数public String() { this.offset = 0; this.count = 0; this.value = new char[0]; } /** * Initializes a newly created {@code String} object so that it represents * the same sequence of characters as the argument; in other words, the * newly created string is a copy of the argument string. Unless an * explicit copy of {@code original} is needed, use of this constructor is * unnecessary since Strings are immutable. * * @param original * A {@code String} */ public String(String original) { int size = original.count; char[] originalValue = original.value; char[] v; if (originalValue.length > size) { // The array representing the String is bigger than the new // String itself. Perhaps this constructor is being called // in order to trim the baggage, so make a copy of the array. int off = original.offset; v = Arrays.copyOfRange(originalValue, off, off + size); } else { // The array representing the String is the same // size as the String, so no point in making a copy. v = originalValue; } this.offset = 0; this.count = size; this.value = v; } /** * Allocates a new {@code String} so that it represents the sequence of * characters currently contained in the character array argument. The * contents of the character array are copied; subsequent modification of * the character array does not affect the newly created string. * * @param value * The initial value of the string */ public String(char[] value) { this.offset = 0; this.count = value.length; this.value = StringValue.from(value); }再看看String类中的contact()函数——将指定字符串联到此字符串的结尾。
public String concat(String str) { int otherLen = str.length(); if (otherLen == 0) { return this; } char[] buf = new char[count + otherLen]; getChars(0, count, buf, 0); str.getChars(0, otherLen, buf, count); return new String(0, count + otherLen, buf); }从Concat函数中,我们可以知道在对字符串使用concat操作后,具体的操作new出一个等同于两个字符串连接总长度的新的char数组,然后将两个字符串复制到新的char数组中,然后返回一个新的String对象。
2.2StringBuilder常见构造函数
public StringBuffer() { super(16); } public StringBuffer(int capacity) { super(capacity); }从StringBuilder的构造函数中,我们可以看见StringBuilder直接调用父类(AbstractStringBuilder)的构造函数,我们再看AbstractStringBuilder的构造函数。
abstract class AbstractStringBuilder implements Appendable, CharSequence { final static int[] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, Integer.MAX_VALUE }; /** * The value is used for character storage. */ char[] value; /** * The count is the number of characters used. */ int count; /** * This no-arg constructor is necessary for serialization of subclasses. */ AbstractStringBuilder() { } /** * Creates an AbstractStringBuilder of the specified capacity. */ AbstractStringBuilder(int capacity) { value = new char[capacity]; } //其他的一些逻辑 }从AbstractStringBuilder的构造函数中,我们可以看出StringBuilder中存储字符串其实用的是一个char数组,capacity其实就是指定这个char数组的大小。
下面我们再从StringBuilder中的append函数看看他具体是怎么做的(以 append(String str) 为例看看)。
public StringBuilder append(String str) { super.append(str); return this; }来看看AbstractStringBuilder类中的append()函数
/** * value 用来存储字符串. */ char value[]; /** * 有效字符串的数目. */ int count; public AbstractStringBuilder append(String str) { if (str == null) { str = "null"; } int len = str.length(); if (len == 0) { return this; } /** * 判断原来用于存储字符串的values的字符串数组有没有足够的大小来存储将要新添加入StringBuilder的字符串。如果不够用,那么就调用expandCapacity(int minimumCapacity)让容量翻两倍 */
int newCount = count + len;
if (newCount > value.length) {
expandCapacity(newCount);
}
//getChars将字符串复制到指定的位置
str.getChars(0, len, value, count);
count = newCount;
return this;
}
2.3 StringBuffer构造函数
/** * Constructs a string buffer with no characters in it and an * initial capacity of 16 characters. */ public StringBuffer() { super(16); } /** * Constructs a string buffer with no characters in it and * the specified initial capacity. * * @param capacity the initial capacity. * @exception NegativeArraySizeException if the capacity * argument is less than 0. */ public StringBuffer(int capacity) { super(capacity); }StringBuffer也是直接调用父类(AbstractStringBuilder)的构造函数(见上面)StringBuffer的append()函数
public synchronized StringBuffer append(String str) { super.append(str); return this; }还是调用父类的append函数,但是在这里有值得注意的地方,StringBuffer的append函数有一个synchronized标识符,也就是说StringBuffer中的append函数是线程安全的,通过继续查阅其他StringBuffer中的函数,我们也可以发现他们有synchronized标识符,这就不难理解为什么StringBuffer是线程安全的,但是很明显加上线程控制会拖慢程序运行的速度,所以如果不需要线程控制,那么最好就用StringBuilder。
3.比较下三者之间的区别:
3.1StringBuffer和StringBuilder之间的区别和联系。
StringBuilder 和 StringBuffer都是可变的字符序列。它们都继承于AbstractStringBuilder,实现了CharSequence接口;StringBuilder是非线程安全的,而StringBuffer是线程安全的,但是很明显加上线程控制会拖慢程序运行的速度,所以如果不需要线程控制,那么最好就用StringBuilder。
3.2 String和StringBuffer、StringBuilder之间的区别。
StringBuffer和StringBuilder对象的内容可以修改;而String对象一旦产生后就不可以被修改,重新赋值其实是两个对象。StringBuffer(StringBuilder)的内部实现方式和String不同,StringBuffer在进行字符串处理时,不生成新的对象,在内存使用上要优于String类。所以在实际使用时,如果经常需要对一个字符串进行修改,例如插入、删除等操作,使用StringBuffer要更加适合一些。StringBuffer对象的append效率要高于String对象的"+"连接操作。
参考:
/article/4763105.html
相关文章推荐
- Android开发UI之去掉title bar
- Jenkins build失败条件
- setuid seteuid setreuid 三个函数讲解
- NGUI学习笔记(五):缓动
- UVA 10735 Euler Circuit 混合图的欧拉回路(最大流,fluery算法)
- UITextField、UILabel和 UITextView四个容易混淆的属性
- Hadoop 管理工具HUE配置
- Win10 RTM Build 10240准正式版简体中文ISO镜像下载 (附KMS激活密钥)
- String,StringBuffer与StringBuilder的区别??
- request.getParameter(param) 的中文乱码问题
- egret GUI 和 egret Wing 是我看到h5 最渣的设计
- android BuildConfig Debug的妙用
- ios uitableview group模式顶部有个空白
- ERROR/Zygote(33): setreuid() failed
- UINavigationController与UITabbarController的样式
- select, iocp, epoll,kqueue及各种I/O复用机制
- [UEFI启动教程][第三章]BIOS锁定纯UEFI启动的解锁办法
- Arduino Pro or Pro Mini, ATmega328 (5V, 16 MHz)成功烧录方法
- handsontable-developer guide-cell function
- handsontable-developer guide-cell editor