簡體   English   中英

在 Java 中,我什么時候應該更喜歡 String 而不是 StringBuilder 反之亦然?

[英]In Java, when should I prefer String over StringBuilder vice versa?

我知道 StringBuilder 應該比 String 更受歡迎,因為 String 將保存在常量字符串池中,並且為其分配新值不會覆蓋以前的值。 但是,StringBuilder 是一個覆蓋其先前值的對象。

  • 在什么情況下我應該在 StringBuilder 上使用 String ,反之亦然。
  • 另外,如果我在 Hibernate 的支持類中有 String 類型的變量,我應該使用 StringBuilder 嗎? 如何?

     ... Result result = (Result) criteria.list().get(0); class Result{ String name; String fname; ... }

您應該使用String ,因為String對象緩存在對象池中,並且在您不更改它們時可能會提供更好的性能。

StringBuilder僅在您繼續連接String標記時才有用,這在規范化的數據庫表中不應該是這種情況。

JVM 會進行各種優化,即使您使用連接,JVM 也可能會將該例程重寫為StringBuilder版本。

我將 String 用於固定的文本值。

在創建較大的文本字符串時使用 StringBuilder,例如:

final StringBuilder sb = new StringBuilder();
for(;;){
    sb.append("more text\n");//add text, StringBuilder's size will increase incrementally
    if(this.stop()){
         break;//stop loop
    }
}
final String result = sb.toString();// Create the final result to work with
System.out.println(result);//print result

對同步值使用 StringBuffer 而不是 StringBuilder,有關 StringBuilder 和 StringBuffer 之間的區別,請參閱https://stackoverflow.com/a/355092/928952

JavaDoc: StringBuffer ( http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuffer.html ):

線程安全的、可變的字符序列。 字符串緩沖區類似於字符串,但可以修改。 在任何時間點它都包含一些特定的字符序列,但是序列的長度和內容可以通過某些方法調用來改變

JavaDoc:StringBuilder( http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html ):

一個可變的字符序列。 此類提供與 StringBuffer 兼容的 API,但不保證同步。 此類旨在用作 StringBuffer 的替代品,用於在單個線程使用字符串緩沖區的地方(通常是這種情況)。 在可能的情況下,建議優先使用此類而不是 StringBuffer,因為在大多數實現下它會更快。

JavaDoc:字符串( http://docs.oracle.com/javase/7/docs/api/java/lang/String.html ):

String 類表示字符串。 Java 程序中的所有字符串文字,例如“abc”,都是作為此類的實例實現的。 字符串是常量; 它們的值在創建后無法更改。 字符串緩沖區支持可變字符串。 因為 String 對象是不可變的,所以它們可以共享

基本上,您將使用 String 作為文本的常量(不可變)。

一個簡單的經驗法則(String 是表示字符串的類型。StringBuilder 是可變字符流)

使用String表示文本值。 根據定義,Java 提供了字符串值的池化,從而為您提供了一些空間優化。 在您的應用程序在文件批處理期間處理數百萬個文本值的場景中考慮這一點。 所以作為一個例子。

  String str1 = "Test";
  String str2 = "Test";

這里, str1 == str2 (相同的參考)

此外, +運算符在 String 中重載以從不同類型構造 String 。 這可以在構造小字符串時使用(在內部它是使用StringBuilder完成的,所以不用擔心) - 但不能在循環時使用。

僅當您使用不同類型的小塊構建目標 String 時(尤其是在循環內),才使用StringBuilder (或舊版StringBuffer ),這將幫助您避免在字符串池中放置不必要的字符串片段。

   StringBuilder s1 = new StringBuilder("test");
   StringBuilder s2 = new StringBuilder("test");

這里,s1 != s2

另外,我不認為您可以通過某種方式操縱 StringBuilder/Buffer 的編碼 - 同時 String 允許這樣做。

編輯:表示 Hibernate 實體:始終使用String表示類中的文本類型。 出於上述原因。這應該像肌肉記憶一樣來找你。 例如,原始類型的intfloatchar等和文本類型的String 僅使用構建器來構建字符串而不是表示類型,除非這是一些奇怪的要求。

當你必須對字符串進行大量修改時,應該使用 java.lang.StringBuilder 類。我們知道 String 對象是不可變的,所以如果你選擇對 String 對象進行大量操作,你最終會String 池中有很多廢棄的 String 對象。 (即使在現在有數 GB RAM 的情況下,將寶貴的內存浪費在丟棄的 String 池對象上也不是一個好主意。)另一方面,StringBuilder 類型的對象可以反復修改,而不會留下大量丟棄的影響。字符串對象。

String x = "abc";
x.concat("def");
System.out.println("x = " + x); // output is "x = abc"


StringBuffer sb = new StringBuffer("abc");
sb.append("def");
System.out.println("sb = " + sb); // output is "sb = abcdef"

字符串是不可變對象,一旦創建就無法更改。 創建為字符串的對象存儲在常量字符串池中。 Java 中的每個不可變對象都是線程安全的,這意味着 String 也是線程安全的。 兩個線程不能同時使用字符串。字符串一旦分配就不能更改。

String  demo = "Test1" ;

上述對象存儲在常量字符串池中,其值不可修改。

demo="Test2" ;

在常量池中創建新的“Test2”字符串並由演示變量引用

StringBuilder 對象是可變的,我們可以更改存儲在對象中的值。 這實際上意味着,如果使用 StringBuilder 對象執行諸如 append 之類的字符串操作將比 String 對象更有效。

StringBuilder demo2= new StringBuilder("Test1");

上述對象也存儲在堆中,其值可以修改

demo2=new StringBuilder("Test1"); 

上面的語句是正確的,因為它修改了 StringBuilder 中允許的值。

因此,您應該在需要經常更新/修改字符串的地方使用 stringBuilder。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM