如题所述
javaä¸StringãStringBufferãStringBuilderæ¯ç¼ç¨ä¸ç»å¸¸ä½¿ç¨çå符串类ï¼ä»ä»¬ä¹é´çåºå«ä¹æ¯ç»å¸¸å¨é¢è¯ä¸ä¼é®å°çé®é¢ãç°å¨æ»ç»ä¸ä¸ï¼ççä»ä»¬çä¸åä¸ç¸åã
1.å¯åä¸ä¸å¯å
ããStringç±»ä¸ä½¿ç¨å符æ°ç»ä¿åå符串ï¼å¦ä¸å°±æ¯ï¼å 为æâfinalâ修饰符ï¼æ以å¯ä»¥ç¥éstring对象æ¯ä¸å¯åçã
ããããprivate final char value[];
ããStringBuilderä¸StringBufferé½ç»§æ¿èªAbstractStringBuilderç±»ï¼å¨AbstractStringBuilderä¸ä¹æ¯ä½¿ç¨å符æ°ç»ä¿åå符串ï¼å¦ä¸å°±æ¯ï¼å¯ç¥è¿ä¸¤ç§å¯¹è±¡é½æ¯å¯åçã
ããããchar[] value;
2.æ¯å¦å¤çº¿ç¨å®å ¨
ããStringä¸ç对象æ¯ä¸å¯åçï¼ä¹å°±å¯ä»¥ç解为常éï¼æ¾ç¶çº¿ç¨å®å ¨ã
ããAbstractStringBuilderæ¯StringBuilderä¸StringBufferçå ¬å ±ç¶ç±»ï¼å®ä¹äºä¸äºå符串çåºæ¬æä½ï¼å¦expandCapacityãappendãinsertãindexOfçå ¬å ±æ¹æ³ã
ããStringBuffer对æ¹æ³å äºåæ¥éæè 对è°ç¨çæ¹æ³å äºåæ¥éï¼æ以æ¯çº¿ç¨å®å ¨çãçå¦ä¸æºç ï¼
1 public synchronized StringBuffer reverse() {2 super.reverse();
3 return this;
4 }
5
6 public int indexOf(String str) {
7 return indexOf(str, 0); //åå¨ public synchronized int indexOf(String str, int fromIndex) æ¹æ³
8 }
ããStringBuilder并没æ对æ¹æ³è¿è¡å åæ¥éï¼æ以æ¯é线ç¨å®å ¨çã
3.StringBuilderä¸StringBufferå ±åç¹
ããStringBuilderä¸StringBufferæå ¬å ±ç¶ç±»AbstractStringBuilder(æ½è±¡ç±»)ã
ããæ½è±¡ç±»ä¸æ¥å£çå ¶ä¸ä¸ä¸ªåºå«æ¯ï¼æ½è±¡ç±»ä¸å¯ä»¥å®ä¹ä¸äºåç±»çå ¬å ±æ¹æ³ï¼åç±»åªéè¦å¢å æ°çåè½ï¼ä¸éè¦éå¤åå·²ç»åå¨çæ¹æ³ï¼èæ¥å£ä¸åªæ¯å¯¹æ¹æ³çç³æå常éçå®ä¹ã
ããStringBuilderãStringBufferçæ¹æ³é½ä¼è°ç¨AbstractStringBuilderä¸çå ¬å ±æ¹æ³ï¼å¦super.append(...)ãåªæ¯StringBufferä¼å¨æ¹æ³ä¸å synchronizedå ³é®åï¼è¿è¡åæ¥ã
ããæåï¼å¦æç¨åºä¸æ¯å¤çº¿ç¨çï¼é£ä¹ä½¿ç¨StringBuilderæçé«äºStringBufferã
2. StringBuffer与StringBuilder,他们是字符串变量,是可改变的对象,每当我们用它们对字符串做操作时,实际上是在一个对象上操作的,不像String一样创建一些对象进行操作,所以速度就快了。
3. StringBuilder:线程非安全的
StringBuffer:线程安全的
当我们在字符串缓冲去被多个线程使用是,JVM不能保证StringBuilder的操作是安全的,虽然他的速度最快,但是可以保证StringBuffer是可以正确操作的。当然大多数情况下就是我们是在单线程下进行的操作,所以大多数情况下是建议用StringBuilder而不用StringBuffer的,就是速度的原因。
对于三者使用的总结:1.如果要操作少量的数据用 = String
2.单线程操作字符串缓冲区 下操作大量数据 = StringBuilder
3.多线程操作字符串缓冲区 下操作大量数据 = StringBuffer
可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。
StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。
例如,如果 z 引用一个当前内容是“start”的字符串缓冲区对象,则此方法调用 z.append("le") 会使字符串缓冲区包含“startle”,而 z.insert(4, "le") 将更改字符串缓冲区,使之包含“starlet”。
通常,如果 sb 引用 StringBuilder 的一个实例,则 sb.append(x) 和 sb.insert(sb.length(), x) 具有相同的效果。
只要发生有关源序列(如在源序列中追加或插入)的操作,该类就只在执行此操作的字符串缓冲区上而不是在源上实现同步。
每个字符串缓冲区都有一定的容量。只要字符串缓冲区所包含的字符序列的长度没有超出此容量,就无需分配新的内部缓冲区数组。如果内部缓冲区溢出,则此容量自动增大。从 JDK 5 开始,为该类补充了一个单个线程使用的等价类,即 StringBuilder。与该类相比,通常应该优先使用 StringBuilder 类,因为它支持所有相同的操作,但由于它不执行同步,所以速度更快。
java.lang.StringBuilder一个可变的字符序列。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。
在 StringBuilder 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串生成器中。append 方法始终将这些字符添加到生成器的末端;而 insert 方法则在指定的点添加字符。
例如,如果 z 引用一个当前内容为“start”的字符串生成器对象,则该方法调用 z.append("le") 将使字符串生成器包含“startle”,而 z.insert(4, "le") 将更改字符串生成器,使之包含“starlet”。
通常,如果 sb 引用 StringBuilder 的实例,则 sb.append(x) 和 sb.insert(sb.length(), x) 具有相同的效果。 每个字符串生成器都有一定的容量。只要字符串生成器所包含的字符序列的长度没有超出此容量,就无需分配新的内部缓冲区。如果内部缓冲区溢出,则此容量自动增大。
将 StringBuilder 的实例用于多个线程是不安全的。如果需要这样的同步,则建议使用 StringBuffer。
这三个类之间的区别主要是在两个方面,即运行速度和线程安全这两方面。
先说运行速度,或者说是执行速度,在这方面运行速度快慢为:StringBuilder > StringBuffer > String
String最慢的原因:
String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。
2. 再来说线程安全
在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的
如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder。
3. 总结一下
String:适用于少量的字符串操作的情况
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况