Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

StringBuilder vs. String considering replace

When doing concatenating lots of strings, I have been recommended to do it using a StringBuilder as such:

StringBuilder someString = new StringBuilder("abc"); someString.append("def"); someString.append("123"); someString.append("moreStuff"); 

as opposed to

String someString = "abc"; someString = someString + "def"; someString = someString + "123"; someString = someString + "moreStuff"; 

which would result in the creation of quite a few Strings, as opposed to one.

Now, I need to do a similar thing, but instead of using concatenation I use the replace method of String as such:

String someString = SOME_LARGE_STRING_CONSTANT; someString = someString.replace("$VARIABLE1", "abc"); someString = someString.replace("$VARIABLE2", "def"); someString = someString.replace("$VARIABLE3", "123"); someString = someString.replace("$VARIABLE4", "moreStuff"); 

To accomplish the same thing using StringBuilder, I have to do this, just for one replace:

someString.replace(someString.indexOf("$VARIABLE1"), someString.indexOf("$VARIABLE1")+10, "abc"); 

So my question is: "Is it better to use String.replace and have lots of extra Strings created, or to use StringBuilder still, and have lots of long winded lines such as the one above?"

like image 262
DanielGibbs Avatar asked Feb 11 '11 04:02

DanielGibbs


People also ask

Is StringBuilder replace faster?

Replace() was faster by about 20% every time swapping out 8-10 letter words. Try it for yourself if you want your own empirical evidence.

When should I use string instead of StringBuilder?

If you are using two or three string concatenations, use a string. StringBuilder will improve performance in cases where you make repeated modifications to a string or concatenate many strings together. In short, use StringBuilder only for a large number of concatenations.

Is StringBuilder more efficient than string?

So from this benchmark test we can see that StringBuilder is the fastest in string manipulation. Next is StringBuffer , which is between two and three times slower than StringBuilder .

Should you use StringBuilder to construct last text instead of just adding strings?

I think we should go with StringBuilder append approach. Reason being : The String concatenate will create a new string object each time (As String is immutable object) , so it will create 3 objects. With String builder only one object will created[StringBuilder is mutable] and the further string gets appended to it.


2 Answers

It is true that StringBuilder tends to be better than concatenating or modifying Strings manually, since StringBuilder is mutable, while String is immutable and you need to create a new String for each modification.

Just to note, though, the Java compiler will automatically convert an example like this:

String result = someString + someOtherString + anotherString; 

into something like:

String result = new StringBuilder().append(someString).append(someOtherString).append(anotherString).toString(); 

That said, unless you're replacing a whole lot of Strings, go for whichever is more readable and more maintainable. So if you can keep it cleaner by having a sequence of 'replace' calls, go ahead and do that over the StringBuilder method. The difference will be negligible compared to the stress you save from dealing with the sad tragedy of micro-optimizations.

PS

For your code sample (which, as OscarRyz pointed out, won't work if you have more than one "$VARIABLE1" in someString, in which case you'll need to use a loop), you could cache the result of the indexOf call in:

someString.replace(someString.indexOf("$VARIABLE1"), someString.indexOf("$VARIABLE1")+10, "abc"); 

With

int index = someString.indexOf("$VARIABLE1");     someString.replace(index, index+10, "abc"); 

No need to search the String twice :-)

like image 124
Zach L Avatar answered Sep 17 '22 12:09

Zach L


Guess what? If you are running with Java 1.5+ the concatenation works the same with string literals

  String h = "hello" + "world"; 

and

  String i = new StringBuilder().append("hello").append("world").toString(); 

Are the same.

So, the compiler did the work for you already.

Of course better would be:

 String j = "hellworld"; // ;)  

As for the second, yeap, that's preferred, but should't be that hard, with the power of "search and replace" and a bit of regex foo

For instance you can define a method like the one in this sample:

  public static void replace( String target, String replacement,                                StringBuilder builder ) {      int indexOfTarget = -1;     while( ( indexOfTarget = builder.indexOf( target ) ) >= 0 ) {        builder.replace( indexOfTarget, indexOfTarget + target.length() , replacement );     }   } 

And your code currently looks like this:

someString = someString.replace("VARIABLE1", "abc"); someString = someString.replace("VARIABLE2", "xyz"); 

All you have to do is grab text editor an trigger something like this vi search and replace:

%s/^.*("\(.*\)".\s"\(.*\)");/replace("\1","\2",builder); 

That read: "take anything in parenthesis and that looks like a string literal, and put it in this other string".

And your code will look from this:

someString = someString.replace("VARIABLE1", "abc"); someString = someString.replace("VARIABLE2", "xyz"); 

to this:

replace( "VARIABLE1", "abc", builder ); replace( "VARIABLE2", "xyz", builder ); 

In no time.

Here's a working demo:

class DoReplace {    public static void main( String ... args ) {     StringBuilder builder = new StringBuilder(        "LONG CONSTANT WITH VARIABLE1 and  VARIABLE2 and VARIABLE1 and VARIABLE2");     replace( "VARIABLE1", "abc", builder );     replace( "VARIABLE2", "xyz", builder );     System.out.println( builder.toString() );   }   public static void replace( String target, String replacement,                                StringBuilder builder ) {      int indexOfTarget = -1;     while( ( indexOfTarget = builder.indexOf( target ) ) > 0 ) {        builder.replace( indexOfTarget, indexOfTarget + target.length() ,                         replacement );     }   } } 
like image 40
OscarRyz Avatar answered Sep 21 '22 12:09

OscarRyz