9

I know StringBuilder should be preferred over String because String will be kept in Constant String Pool and assigning a new value to it does not override the previous values. However, StringBuilder is an object that overrides its previous value.

  • In what cases should I use String over StringBuilder vice versa.
  • Also If I have variables of type String in backing classes of Hibernate should I use StringBuilder? How?

    ...
    Result result = (Result) criteria.list().get(0);
    
    
    class Result{
       String name;
       String fname;
       ...
    }
    
Vlad Mihalcea
  • 142,745
  • 71
  • 566
  • 911
Daniel Newtown
  • 2,873
  • 8
  • 30
  • 64
  • Only a few strings (literal strings, string-valued constant expressions and strings you call `intern()` on) will be kept in the pool. Why do you imply this is bad? What do you mean by "overriding previous value"? Assigning to a `String` variable does the same as assigning to a `StringBuilder` variable. Are you talking about mutability vs. immutability? Are you sure about when to "prefer" `StringBuilder`? – xehpuk Jun 25 '15 at 11:25
  • @xehpuk as I know, when you assign a new value to String it removes the reference to its previous value and add the reference of the new one therefore the previous value stays in memory waiting for GC. Whereas StringBuilder replaces the new value with the previous one. I am not sure and thats why in the first bullet point I included (vice vesa) – Daniel Newtown Jun 25 '15 at 22:10

5 Answers5

3

You should use String, because String objects are cached in an object pool and might deliver better performance when you don't change them.

A StringBuilder is only useful when you keep on concatenating String tokens, which shouldn't be the case in a well normalized database table.

The JVM does all sorts of optimizations and chances are that even if you use concatenation the JVM might rewrite that routine to a StringBuilder version.

Vlad Mihalcea
  • 142,745
  • 71
  • 566
  • 911
  • Also note that in many cases concatenation can and should be avoided without resorting through an intermediary `StringBuilder`. Case 1 - "jdbc" - use of bind variables vs concatenating strings; case 2 - "System.out" - multiple calls to `print` or `println`, or chaining `System.out` as in `System.out.append("Hello ").append(name);` – YoYo Jun 30 '15 at 23:37
2

I'd use String for text values that are fixed.

Use StringBuilder when you are creating a larger text String like:

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

Use StringBuffer instead of StringBuilder for synchronized values, see https://stackoverflow.com/a/355092/928952 for difference between StringBuilder and StringBuffer.

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

A thread-safe, mutable sequence of characters. A string buffer is like a String, but can be modified. At any point in time it contains some particular sequence of characters, but the length and content of the sequence can be changed through certain method calls

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

A mutable sequence of characters. This class provides an API compatible with StringBuffer, but with no guarantee of synchronization. This class is designed for use as a drop-in replacement for 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 StringBuffer as it will be faster under most implementations.

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

The String class represents character strings. All string literals in Java programs, such as "abc", are implemented as instances of this class. 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

Basically you'll use String for constants (immutable) of text.

Community
  • 1
  • 1
Danielson
  • 2,605
  • 2
  • 28
  • 51
  • In that case does that mean my hibernate code is correct? – Daniel Newtown Jun 24 '15 at 09:02
  • I don't see an error... But that doesn't mean the error is not somewhere else. – Danielson Jun 24 '15 at 09:03
  • I didn't downvote, but I would avoid using StringBuilder. Making things thread-safe needs careful implementation considerations, not turning blindly to thread-safe implementations for all your API's. In a lot of cases, even in a multithreaded context, there is not always need to safeguard all parts of your code. Thread-safe implementations like StringBuilder, and some Collection implementations add a lot of synchronization overhead. – YoYo Jun 30 '15 at 23:46
  • I wouldn't use String building over different threads, sounds too error prone. Also I can't think of a reason why this would be necessary - but maybe others will – Danielson Jul 01 '15 at 05:47
2

A simple rule of thumb (String is a type that represents character strings. StringBuilder a stream of mutable characters)

Use String to represent text values. By definition Java provides pooling of string values and thus providing you some space optimization. Think of this in a scenario where your application is dealing with millions of text values during a file batch processing. So as an example.

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

Here, str1 == str2 ( same reference)

Also, + operator is overloaded in String to construct String from different types. This can be used when constructing small Strings ( internally it gets done using StringBuilder so no worries) - but not while looping.

Use StringBuilder(or old counterpart StringBuffer) only when you are constructing a target String using small pieces of different types - and especially inside a loop - this will help you to avoid placing unnecessary string fragments in the string pool.

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

Here, s1 != s2

Also, I do not think there is someway you can manipulate the encoding of StringBuilder/Buffer - Meanwhile String allows this.

Edit: Representing Hibernate entities : Always use String to represent a text type in your class. For reasons stated above.This should come to you like muscle memory. For example, int, float, char etc for primitive types and String for text type. Use the builder only to build strings and not to represent a type unless that is some strange requirement.

ring bearer
  • 20,383
  • 7
  • 59
  • 72
  • 1
    Please see posts like http://stackoverflow.com/questions/88838/how-to-convert-strings-to-and-from-utf8-byte-arrays-in-java – ring bearer Jun 25 '15 at 04:11
1

The java.lang.StringBuilder classes should be used when you have to make a lot of modifications to strings of characters.As we know String objects are immutable, so if you choose to do a lot of manipulations with String objects, you will end up with a lot of abandoned String objects in the String pool. (Even in these days of gigabytes of RAM, it's not a good idea to waste precious memory on discarded String pool objects.) On the other hand, objects of type StringBuilder can be modified over and over again without leaving behind a great effluence of discarded String objects.

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"
Nitesh Soomani
  • 572
  • 5
  • 12
  • 1
    String manipulation does not leave objects in the "string pool". There is a pool of unique strings, but strings only end up there if you `intern()` them or if they come from a string literal in your source code. And printing a `StringBuffer` first *converts it to a `String`* so this doesn't help. – Erwin Bolwidt Jun 25 '15 at 07:39
0

String is immutable object,once created can not be changed. The object created as a String is stored in the Constant String Pool. Every immutable object in Java is thread safe ,that implies String is also thread safe. String can not be used by two threads simultaneously.String once assigned can not be changed.

String  demo = "Test1" ;

The above object is stored in constant string pool and its value can not be modified.

demo="Test2" ;

new "Test2" string is created in constant pool and referenced by the demo variable

StringBuilder objects are mutable, we can make changes to the value stored in the object. What this effectively means is that string operations such as append would be more efficient if performed using StringBuilder objects than String objects.

StringBuilder demo2= new StringBuilder("Test1");

The above object too is stored in the heap and its value can be modified

demo2=new StringBuilder("Test1"); 

Above statement is right as it modifies the value which is allowed in the StringBuilder.

So you should be using stringBuilder where you required to update/modify the string frequently.

Abhijit Bashetti
  • 8,518
  • 7
  • 35
  • 47
  • 1
    "Objects created as a string" are not stored in the "constant string pool" by default. Strings only end up there if you `intern()` them or if they come from a string literal in your source code. `new StringBuilder("Test1")` also stored the string `"Test1"` in the "constant string pool" because `"Test1"` is a string, so they're is no benefit in that respect from using StringBuilder/Buffer. – Erwin Bolwidt Jun 25 '15 at 07:44
  • yes if the string is intialised with new then intern comes into the picture and then it will move to the pool – Abhijit Bashetti Jun 25 '15 at 08:40
  • No Abhijit, a string constructed using `new` does not move to the pool. Only a call to `intern()` or having a string literal in you class will do that. – Erwin Bolwidt Jun 25 '15 at 08:43
  • sorry for the short reply. And yes I agree with your statement. Thats whats I tried to mention here is when a string is initialized with new and then if you call intern, it will move to the pool. Intern is the method which will add the string to the pool if they are nit present there... – Abhijit Bashetti Jun 25 '15 at 08:50