String vs StringBuffer vs StringBuilder
- 2022 年 8 月 25 日
- 筆記
String vs StringBuffer vs StringBuilder
本文翻譯自://www.digitalocean.com/community/tutorials/string-vs-stringbuffer-vs-stringbuilder
字元串是Java中使用最廣泛的類之一。StringBuffer和StringBuilder類提供了操作字元串的方法。本文將研究StringBuffer和StringBuilder之間的區別。StringBuffer vs StringBuilder是一個流行的Java面試問題。
String vs StringBuffer vs StringBuilder
字元串是核心java訪談中最重要的主題之一。如果您正在編寫一個在控制台上列印內容的程式,則使用字元串。本文旨在關注字元串類的主要特性。然後比較StringBuffer和StringBuilder類。
String in Java
-
字元串類表示字元串,我們可以用兩種方式實例化字元串。
String str = "ABC"; // or String str = new String("ABC");
-
字元串在Java中是不可變的。因此,它適用於多執行緒環境。我們可以跨函數共享它,因為不需要擔心數據不一致。
-
當我們使用雙引號創建字元串時,JVM首先在字元串池中查找具有相同值的字元串。如果找到,則返回池中字元串對象的引用。否則,它將在字元串池中創建字元串對象並返回引用。JVM通過在不同執行緒中使用相同的字元串來節省大量記憶體。
-
如果使用新運算符創建字元串,則會在堆記憶體中創建該字元串。
-
字元串的+運算符重載。我們可以用它連接兩個字元串。儘管在內部它使用StringBuffer來執行此操作。
-
字元串重寫equals()和hashCode()方法。只有當兩個字元串具有相同的字元序列時,它們才相等。equals()方法區分大小寫。如果要查找不區分大小寫的檢查,則應使用equalsIgnoreCase()方法。
-
字元串對字元流使用UTF-16編碼。
-
字元串是最後一個類。所有欄位均為最終欄位,但「private int hash」除外。此欄位包含hashCode())函數值。只有在第一次調用hashcode()方法並將其快取在此欄位中時,才會計算hashcode值。此外,通過一些計算,使用字元串類的最終欄位生成哈希。因此,每次調用hashCode()方法時,都會產生相同的輸出。對於調用者來說,似乎每次都在進行計算,但在內部,它被快取在哈希欄位中。
String vs StringBuffer
由於字元串在Java中是不可變的,每當我們進行字元串操作(如連接、子字元串等)時,它會生成一個新字元串,並丟棄舊字元串進行垃圾收集。這些都是繁重的操作,並在堆中生成大量垃圾。因此,Java提供了StringBuffer和StringBuilder類,它們應該用於字元串操作。StringBuffer和StringBuilder是Java中的可變對象。它們為字元串操作提供了append()、insert()、delete()和substring()方法。
StringBuffer vs StringBuilder
在Java1.4之前,StringBuffer是字元串操作的唯一選擇。但是,它有一個缺點,它的所有公共方法都是同步的。StringBuffer提供執行緒安全性,但以性能為代價。在大多數情況下,我們不會在多執行緒環境中使用字元串。因此,Java1.5引入了一個新的類StringBuilder,除了執行緒安全和同步之外,它與StringBuffer類似。StringBuffer有一些額外的方法,如子字元串、長度、容量、trimToSize等。然而,這些方法不是必需的,因為您在字元串中也有這些方法。這就是為什麼這些方法從未在StringBuilder類中實現。StringBuffer是在Java 1.0中引入的,而StringBuilder類是在查看了StringBufer的缺點之後在Java 1.5中引入的。如果您處於單執行緒環境中或不關心執行緒安全,則應使用StringBuilder。否則,請使用StringBuffer進行執行緒安全操作。
StringBuilder vs StringBuffer Performance
我試圖檢查對性能的影響,因為與一個示常式序同步,該程式多次對StringBuffer和StringBuilder對象執行「append()」。
package com.journaldev.java;
import java.util.GregorianCalendar;
public class TestString {
public static void main(String[] args) {
System.gc();
long start=new GregorianCalendar().getTimeInMillis();
long startMemory=Runtime.getRuntime().freeMemory();
StringBuffer sb = new StringBuffer();
//StringBuilder sb = new StringBuilder();
for(int i = 0; i<10000000; i++){
sb.append(":").append(i);
}
long end=new GregorianCalendar().getTimeInMillis();
long endMemory=Runtime.getRuntime().freeMemory();
System.out.println("Time Taken:"+(end-start));
System.out.println("Memory used:"+(startMemory-endMemory));
}
}
我還為StringBuffer對象運行了相同的程式碼,以檢查時間和記憶體值。我對每種情況執行了5次程式碼,然後計算了平均值。
Value of i | StringBuffer (Time, Memory) | StringBuilder (Time, Memory) |
---|---|---|
10,00,000 | 808, 149356704 | 633, 149356704 |
1,00,00,000 | 7448, 147783888 | 6179, 147783888 |
很明顯,即使在單執行緒環境中,StringBuilder的性能也優於StringBuffer。這種性能差異可能是由StringBuffer方法中的同步引起的。
String vs StringBuffer vs StringBuilder
-
字元串是不可變的,而StringBuffer和StringBuilder是可變的類。
-
StringBuffer是執行緒安全和同步的,而StringBuilder不是。這就是為什麼StringBuilder比StringBuffer快。
-
字元串連接運算符(+)在內部使用StringBuffer或StringBuilder類。
-
對於非多執行緒環境中的字元串操作,我們應該使用StringBuilder,否則使用StringBuffer類。
以上是對字元串、StringBuffer和StringBuilder之間差異的簡要總結。在大多數一般編程場景中,StringBuilder比StringBuffer更適合。
參考文獻: