一. 介紹 String、StringBuffer、StringBuilder: 前言: String、StringBuffer、StringBuilder 均在java.lang包下; String: 在Java中,String是一個特殊的引用類型,用於表示文本字元串。它提供了許多方法來操作和處理 ...
一. 介紹 String、StringBuffer、StringBuilder:
前言: String、StringBuffer、StringBuilder 均在java.lang包下;
String: 在Java中,String是一個特殊的引用類型,用於表示文本字元串。它提供了許多方法來操作和處理字元串,比如連接、截取、查找、替換等。String類內部使用字元數組(char[])來存儲字元串的內容,且value欄位被final修飾,這意味著String對象一旦創建後,其值就不可改變。String對象的值存儲在常量池中,每次修改操作都會創建一個新的字元串對象,並且如果常量池中已經存在相同內容的字元串,就會直接引用該字元串而不創建新對象。
StringBuffer:Java中的一個可變字元串類,用於處理字元串。它可以被修改,因此適合在需要頻繁更改字元串內容的情況下使用。StringBuffer提供了許多方法用於插入、刪除和修改字元串,並且支持線程安全操作。與String類不同,StringBuffer對象可以在已有的字元串基礎上進行操作,且地址值不會改變;StringBuffer 類是可變的,它不會在常量池中創建新的常量。當你使用 StringBuffer 修改一個字元串時,它會在堆記憶體中創建一個新的字元串對象,並且在需要的時候調整其容量。
StringBuilder:與StringBuffer類似,它允許在已有字元串的基礎上進行修改、添加和刪除操作,而不需要創建新的字元串對象。通過使用StringBuilder,可以高效地進行字元串拼接、插入、替換等操作,特別適用於頻繁修改字元串內容的場景,每次修改只是對自身做出修改。StringBuilder具有較高的性能和效率,並且是線程不安全的,適用於單線程環境下的字元串處理。
二. 區別:
1. 不可變性:
- String類是不可變的,一旦創建就不能被修改。任何對字元串的操作都會創建一個新的字元串對象。
- StringBuffer和StringBuilder類是可變的,可以在原始字元串上進行修改,無需創建新的對象。
2. 線程安全性:
- String類是線程安全的,因為它的方法在內部使用了同步機制,適用於多線程環境。
- StringBuffer類是線程安全的,所有的方法都使用了同步鎖,可以在多線程環境中使用。
- StringBuilder類是非線程安全的,它的方法沒有使用同步鎖,適用於單線程環境。
3. 性能:
- 由於String類的不可變性,每次進行拼接、替換等操作時都會創建新的對象,對性能有一定影響。
- StringBuffer類是可變的,適用於頻繁操作字元串的情況,但是由於使用了線程安全同步機制,相對較慢。
- StringBuilder類是可變的,適用於單線程下頻繁操作字元串的情況,在性能上優於StringBuffer。
綜上所述,如果你需要進行頻繁的字元串拼接、替換等操作,並且在多線程環境下使用,應該選擇StringBuffer類。如果在單線程環境下進行字元串操作,可以選擇StringBuilder類以獲得更好的性能。而如果你不需要修改字元串,只是進行簡單的字元串操作,那麼使用String類即可。
三. 代碼展示
不可變性區別展示:
public static void main(String[] args) { // String String str = "Hello"; System.out.println(str.hashCode()); String str1 = str + "word"; System.out.println(str1.hashCode()); // StringBuilder StringBuilder sb = new StringBuilder("Hello"); System.out.println(sb.hashCode()); StringBuilder sb1 = sb.append("word"); System.out.println(sb1.hashCode()); // StringBuffer StringBuffer sbf = new StringBuffer("Hello"); System.out.println(sbf.hashCode()); StringBuffer sbf1 = sbf.append("word"); System.out.println(sbf1.hashCode()); } 輸出結果: 69609650 -1093253444 23934342 23934342 22307196 22307196
可以看到String在改變字元串後,HashCode發生改變,而StringBuffer、StringBuilder 沒有變化。
四. 總結
- String:不可變的字元串,線程安全,適合在多線程環境下使用,適用於字元串內容不經常改變的情況,操作少量的數據。
- StringBuffer:可變的字元串,線程安全,適合在多線程環境下使用,適用於頻繁進行字元串操作的情況。
- StringBuilder:可變的字元串,非線程安全,適合在單線程環境下使用,適用於頻繁進行字元串操作的情況。
五. 擴展
1. String 源碼中註釋
* Strings are constant; their values cannot be changed after they * are created. String buffers support mutable strings. * Because String objects are immutable they can be shared.
*字元串是常量;它們的值在創建後不能更改,因為String對象是不可變的,所以它們可以共用。
public final class String implements java.io.Serializable, Comparable<String>, CharSequence { /** The value is used for character storage. */ private final char value[]; /** Cache the hash code for the string */ private int hash; // Default to 0 }
private final char value[]; 底層是字元數組實現,該值是使用final修飾,創建後不能改變。
2. StringBuffer 源碼中註釋
* A thread-safe, mutable sequence of characters. * A string buffer is like a {@link String}, but can be modified. * The principal operations on a {@code StringBuffer} are the * {@code append} and {@code insert} methods, which are * overloaded so as to accept data of any type. * Whenever an operation occurs involving a source sequence (such as * appending or inserting from a source sequence), this class synchronizes * only on the string buffer performing the operation, not on the source.
* 線程安全的可變字元序列,字元串緩衝區類似於String,但是可以修改。
* 主要操作是通過append()、insert() 它們是重載的,以便接受任何類型的數據。
* 每當涉及到源數據的操作發生改變時,(例如從源序列追加或插入)此類進行同步僅在執行操作的字元串緩衝區上,而不是在源數據上。
@Override public synchronized StringBuffer append(Object obj) { toStringCache = null; super.append(String.valueOf(obj)); return this; } @Override public synchronized StringBuffer append(String str) { toStringCache = null; super.append(str); return this; }
StringBuffer 在插入或修改的時候 都會使用synchronized() 確保線程安全性。
3. StringBuilder 源碼註釋
* A mutable sequence of characters. This class provides an API compatible * with {@code StringBuffer}, but with no guarantee of synchronization. * This class is designed for use as a drop-in replacement for * {@code StringBuffer} in places where the string buffer was being * used by a single thread (as is generally the case). Where possible, * it is recommended that this class be used in preference to * {@code StringBuffer} as it will be faster under most implementations. * Instances of {@code StringBuilder} are not safe for * use by multiple threads. If such synchronization is required then it is * recommended that {@link java.lang.StringBuffer} be used.
* 可變的字元串,此類提供與StringBuffer相容的API,但不保證同步。這個類通常情況下用在字元串緩衝區被單個線程使用的地方,作為StringBuffer的替代品。建議優先使用此類而不是StringBuffer,因為在大多數實現中它會更快。
* StringBuilder的實例對於多個線程使用是不安全的。如果需要同步,則建議使用StringBuffer
@Override public StringBuilder append(Object obj) { return append(String.valueOf(obj)); } @Override public StringBuilder append(String str) { super.append(str); return this; }
如果需要線程安全同步,建議使用StringBuffer類。
(๑′ᴗ‵๑) 完!