String vs StringBuffer vs StringBuilder

  • 2022 年 8 月 25 日
  • 筆記

String vs StringBuffer vs StringBuilder

本文翻譯自://www.digitalocean.com/community/tutorials/string-vs-stringbuffer-vs-stringbuilder

image

字元串是Java中使用最廣泛的類之一。StringBuffer和StringBuilder類提供了操作字元串的方法。本文將研究StringBuffer和StringBuilder之間的區別。StringBuffer vs StringBuilder是一個流行的Java面試問題。

String vs StringBuffer vs StringBuilder

字元串是核心java訪談中最重要的主題之一。如果您正在編寫一個在控制台上列印內容的程式,則使用字元串。本文旨在關注字元串類的主要特性。然後比較StringBuffer和StringBuilder類。

String in Java

  1. 字元串類表示字元串,我們可以用兩種方式實例化字元串。

    String str = "ABC";
    // or 
    String str = new String("ABC");
    
  2. 字元串在Java中是不可變的。因此,它適用於多執行緒環境。我們可以跨函數共享它,因為不需要擔心數據不一致。

  3. 當我們使用雙引號創建字元串時,JVM首先在字元串池中查找具有相同值的字元串。如果找到,則返回池中字元串對象的引用。否則,它將在字元串池中創建字元串對象並返回引用。JVM通過在不同執行緒中使用相同的字元串來節省大量記憶體。

  4. 如果使用新運算符創建字元串,則會在堆記憶體中創建該字元串。

  5. 字元串的+運算符重載。我們可以用它連接兩個字元串。儘管在內部它使用StringBuffer來執行此操作。

  6. 字元串重寫equals()和hashCode()方法。只有當兩個字元串具有相同的字元序列時,它們才相等。equals()方法區分大小寫。如果要查找不區分大小寫的檢查,則應使用equalsIgnoreCase()方法。

  7. 字元串對字元流使用UTF-16編碼。

  8. 字元串是最後一個類。所有欄位均為最終欄位,但「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

  1. 字元串是不可變的,而StringBuffer和StringBuilder是可變的類。

  2. StringBuffer是執行緒安全和同步的,而StringBuilder不是。這就是為什麼StringBuilder比StringBuffer快。

  3. 字元串連接運算符(+)在內部使用StringBuffer或StringBuilder類。

  4. 對於非多執行緒環境中的字元串操作,我們應該使用StringBuilder,否則使用StringBuffer類。

    以上是對字元串、StringBuffer和StringBuilder之間差異的簡要總結。在大多數一般編程場景中,StringBuilder比StringBuffer更適合。

    參考文獻: