This question already has answers here:
String concatenation: concat() vs "+" operator
(12 answers)
Closed 8 years ago.
For string concatenation we can use either the concat() or concat operator (+).
I have tried the following performance test and found concat() is faster and a memory efficient way for string concatenation.
String concatenation comparison for 100,000 times:
String str = null;
//------------Using Concatenation operator-------------
long time1 = System.currentTimeMillis();
long freeMemory1 = Runtime.getRuntime().freeMemory();
for(int i=0; i<100000; i++){
str = "Hi";
str = str+" Bye";
}
long time2 = System.currentTimeMillis();
long freeMemory2 = Runtime.getRuntime().freeMemory();
long timetaken1 = time2-time1;
long memoryTaken1 = freeMemory1 - freeMemory2;
System.out.println("Concat operator :" + "Time taken =" + timetaken1 +
" Memory Consumed =" + memoryTaken1);
//------------Using Concat method-------------
long time3 = System.currentTimeMillis();
long freeMemory3 = Runtime.getRuntime().freeMemory();
for(int j=0; j<100000; j++){
str = "Hi";
str = str.concat(" Bye");
}
long time4 = System.currentTimeMillis();
long freeMemory4 = Runtime.getRuntime().freeMemory();
long timetaken2 = time4-time3;
long memoryTaken2 = freeMemory3 - freeMemory4;
System.out.println("Concat method :" + "Time taken =" + timetaken2 +
" Memory Consumed =" + memoryTaken2);
Result
Concat operator: Time taken = 31; Memory Consumed = 2259096
Concat method : Time taken = 16; Memory Consumed = 299592
If concat() is faster than the operator then when should we use concatenation operator (+)?
The concat method always produces a new String with the result of concatenation.
The plus operator is backed by StringBuilder creation, appending all String values you need and further toString() calling on it.
So, if you need to concatenate two values, concat() will be better choice. If you need to concatenate 100 values, you should use the plus operator or explicitly use StringBuilder (e.g. in case of appending in a cycle).
In fact s1 + s2 and s1.concat(s2) are very different.
s1 + s2 is converted by javac into
(new StringBuilder(String.valueOf(s1)).append(s2).toString();
You can see it if you decompile .class. This construct is not very efficient; it involves up to three new char[] allocations and three char[] copy operations.
s1.concat(s2) is always one new char[] + one copy operation, see String.java
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
char buf[] = new char[count + otherLen];
getChars(0, count, buf, 0);
str.getChars(0, otherLen, buf, count);
return new String(0, count + otherLen, buf);
}
Note that new String(int, int, char[]) is String's package private constructor. It uses char buf[] directly, without the usual copying to ensure the buf invisibility for the String immutability.
Your test needs to be running for at least 2 seconds with each loop in a separate method to be meaningful. Short tests can be every difficult to reproduce and compare. From your timing it appears you are using Windows (i.e. because you times are 16 and 31 ms ;) Try System.nanoTime() instead. When your loop iterates over 10,000 times the whole method is compiled. This means your later method is already compiled when it is started.
In answer to your question concat is marginally faster when adding two Strings. However, it comes with a typing and conceptual overhead which is likely to be much greater than the CPU you save. Even based on your tests repeating 100,000 times it saves less than 15 ms, and yet it cost you far, far more than that in your time (which is likely to be worth more) You could find in a future version of the JVM, the difference is optimised always and the complexity of your code is still there.
EDIT: I didn't notice that the memory result was suspect.
String str = null;
//------------Using Concatenation operator-------------
long time1 = System.currentTimeMillis();
long freeMemory1 = Runtime.getRuntime().freeMemory();
for (int i = 0; i < 10000; i++) {
str = "Hi";
str = str + " Bye";
}
long time2 = System.currentTimeMillis();
long freeMemory2 = Runtime.getRuntime().freeMemory();
long timetaken1 = time2 - time1;
long memoryTaken1 = freeMemory1 - freeMemory2;
System.out.println("Concat operator :" + "Time taken =" + timetaken1 + " Memory Consumed= " + memoryTaken1);
str = null;
//------------Using Concat method-------------
long time3 = System.currentTimeMillis();
long freeMemory3 = Runtime.getRuntime().freeMemory();
for (int j = 0; j < 10000; j++) {
str = "Hi";
str = str.concat(" Bye");
}
long time4 = System.currentTimeMillis();
long freeMemory4 = Runtime.getRuntime().freeMemory();
long timetaken2 = time4 - time3;
long memoryTaken2 = freeMemory3 - freeMemory4;
System.out.println("Concat method :" + "Time taken =" + timetaken2 + " Memory Consumed= " + memoryTaken2);
prints when run with -XX:-UseTLAB -mx1g
Concat operator :Time taken =12 Memory Consumed= 1291456
Concat method :Time taken =7 Memory Consumed= 560000
making the ratio of memory usage about 2:1. In the original question the result vary every time you run it, sometimes the .concat() appears to use more.
I believe the 'style' of concatenation is going to make a difference.
For concat(), it internally creates a new char array buffer, and returns a new string based on that char array.
For the + operator, the compiler in fact translate it to use StringBuffer/StringBuilder.
Therefore, if you are concatenating two strings, concat() is definitely a better choice because the number of objects created is only the result String (and the char buffer used inside), while using the + operator will be translated to:
result = strA + strB;
-- translate to -->
result = new StringBuilder(strA).append(strB).toString();
An extra StringBuilder instance is created.
However, if you are concatenating, for example five strings in a row, each concat() will create a new String object. While using the + operator, the compiler will translate the statement to one StringBuilder with multiple append operations. It is definitely saving a lot of unnecessary temporary object instance:
result = strA + strB + strC + strD + strE;
-- translate to -->
result = new StringBuilder(strA).append(strB).append(strC).append(strD).append(strE).toString();
You can always use + if only you use >= Java 1.5 and you don't declare your base String (that you want concatenate) outside of the loop. In Java 1.5 it results in creating new StringBuilder and working on it till your string is complete. That's the fastest way.
Anyway - if you are in a loop (and concatenating strings with +) - every iteration of the loop creates a new StringBuilder - that's not the best idea. So this is where you should force the use of StringBuilder or StringBuffer (thread safe) classes.
Generally, this link clearly answers your question, and gives you complete knowledge:
http://littletutorials.com/2008/07/16/stringbuffer-vs-stringbuilder-performance-comparison/
Though both the operator and the method are giving the same output, the way they work internally differs.
The concat() method that just concatenates str1 with str2 and outputs a string, is more efficient for a small number of concatenations.
But with concatenation operator '+', str1+=str2; will be interpreted as
str1 = new StringBuilder().append(str1).append(str2).toString();
You can use the concat method when using a fewer number of strings to concatenate. But the StringBuilder method would be fast in terms of performance, if you are using a large number of strings.
Actually, both are the same. If you see the code of concat(String paramString) it will return a new object of string, and in the (+) operator it it will also generate a new string object.
If you don't want to create a new object then use string builder to concatenate two strings.
In general it is a bad practice to concatenate Strings with + and with concat(). If you want to create a String use StringBuilder instead.
Related
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
StringBuilder vs String concatenation in toString() in Java
Why are StringBuilders better to use than normal String Concatenation?
The java compiler these days is smart enough that it will use StringBuilder to concatenate strings anyway.
This makes the following code identical
System.out.println("test = "+test+" test2 = "+test2);
System.out.println((new StringBuilder()).append("test = ").append(test).append("test2 = ").append(test2).toString());
So if your strings fall on a single executable line, you should never be afraid of using string concatanation.
However if you're looping through an array of something and concatenating the strings together the java runtime will be creating all these new StringBuilder then concatenating them together, so it's more efficient in this case to supply your own single instance of StringBuilder
StringBuilder sb = new StringBuilder();
for(String test : testStrings) {
sb.append(" ").appendtest);
}
Because Strings are immutable. When you do a string concatenation, you create many strings as temporaries that must then be garbage collected. With StringBuilder, there's an underlying mutable data structure, so you just keep using that.
The effect is to both limit the amount of GC and reduce the number of JVM instructions that are executed. Instructions aren't usually a big issue, but I've seen bad uses of string concatenation push a JVM into massive GC loads.
StringBuilder is mutable so you are not creating new string.
StringBuilder does not create new Strings in the pool on operations such as concatenation, substring e.t.c. In short, every time u make an operation on String, a new String is created in the pool.
String x = "abc"
x= x+"def";
so three strings have been created in the pool. "abc", "def". "abcdef".....where as same task would have been achieved by StringBUilder while using only one object.
StringBuilder is recommended over StringBuffer, because StringBuffer is thread safe and have synchronized methods, so until or unless thread safe is required, stringbuilder is recommended as string buffer might cause performance overhead, although negligible.
I decided to put your question to the 'profiler' test by running 3 simple test cases through the YourKit Java Profiler. I performed three tests using String, StringBuilder and StringBuffer.
The source for each is as follows:
public void testString() throws Exception {
for ( int x = 0; x < 10000000; x++ ) {
String s = "the quick brown fox jumped over the lazy dogs. ";
for ( int i = 0 ; i < 5; i++ ) {
s += s;
}
}
}
public void testStringBuilder() throws Exception {
for ( int x = 0; x < 10000000; x++ ) {
StringBuilder s = new StringBuilder("the quick brown fox jumped over the lazy dogs. ");
for ( int i = 0 ; i < 5; i++ ) {
s.append(s);
}
}
}
public void testStringBuffer() throws Exception {
for ( int x = 0; x < 10000000; x++ ) {
StringBuffer s = new StringBuffer("the quick brown fox jumped over the lazy dogs. ");
for ( int i = 0 ; i < 5; i++ ) {
s.append(s);
}
}
}
Each of these test cases was executed with 'Tracing' enabled on a 64-bit JDK1.6_27. Below are the timing results from each test (sorry, had to remove images due to SO limits, posting CSV output instead).
The first thing you'll notice is that in both the String an StringBuffer test, the JVM is using StrinbBuffers as the internal implementation. However, in the String case, the overall performance is much worse. The key to the difference is in the invocation count.
In the String case, use of the concatenation operator ("+=") results in the creation of two StringBuffer instances (see the "Invocation Count" results: 99M vs 48M).
So if you're going to do lots of concatenation, use a StringBuffer directly.
String:
"Name","Time (ms)","Avg. Time (ms)","Own Time (ms)","Invocation Count","Level"
"com.altosresearch.utils.test.StringsTest.testString()","190497","190497","0","1", "7"
"java.lang.StringBuilder.append(String)","117742","0","117742","99825142", "8"
"java.lang.StringBuilder.toString()","46142","0","46142","49912563", "8"
"java.lang.StringBuilder.<init>()","26612","0","26612","49912563", "8"
StringBuilder:
"Name","Time (ms)","Avg. Time (ms)","Own Time (ms)","Invocation Count","Level"
"com.altosresearch.utils.test.StringsTest.testStringBuilder()","90179","90179","0","1", "7"
"java.lang.StringBuilder.append(CharSequence)","79212","0","79212","48924577", "8"
"java.lang.StringBuilder.<init>(String)","10966","0","10966","9784916", "8"
StringBuffer:
"Name","Time (ms)","Avg. Time (ms)","Own Time (ms)","Invocation Count","Level"
"com.altosresearch.utils.test.StringsTest.testStringBuffer()","83518","83518","0","1", "7"
"java.lang.StringBuffer.append(StringBuffer)","73207","0","73207","48694049", "8"
"java.lang.StringBuffer.<init>(String)","10311","0","10311","9738810", "8"
Since strings are immutable, you may want to use the StringBuilder class if you're going to alter the String in the code.
String is immutable so every concat creates a new object, Stringbuffer/builder are mutable. A note is offered at this link
I have code as follows :
String s = "";
for (My my : myList) {
s += my.getX();
}
Findbugs always reports error when I do this.
I would use + if you are manually concatenating,
String word = "Hello";
word += " World!";
However, if you are iterating and concatenating I would suggest StringBuilder,
StringBuilder sb = new StringBuilder();
for (My my : myList) {
sb.append(my.getX());
}
The String object is immutable in Java. Each + means another object. You could use StringBuffer to minimize the amount of created objects.
Each time you do string+=string, it calls method like this:
private String(String s1, String s2) {
if (s1 == null) {
s1 = "null";
}
if (s2 == null) {
s2 = "null";
}
count = s1.count + s2.count;
value = new char[count];
offset = 0;
System.arraycopy(s1.value, s1.offset, value, 0, s1.count);
System.arraycopy(s2.value, s2.offset, value, s1.count, s2.count);
}
In case of StringBuilder, it comes to:
final void append0(String string) {
if (string == null) {
appendNull();
return;
}
int adding = string.length();
int newSize = count + adding;
if (newSize > value.length) {
enlargeBuffer(newSize);
}
string.getChars(0, adding, value, count);
count = newSize;
}
As you can clearly conclude, string + string creates a lot of overhead, and in my opinion should be avoided if possible. If you think using StringBuilder is bulky or to long you can just make a method and use it indirectly, like:
public static String scat(String... vargs) {
StringBuilder sb = new StringBuilder();
for (String str : vargs)
sb.append(str);
return sb.toString();
}
And use it like:
String abcd = scat("a","b","c","d");
In C# I'm told its about as same as string.Concat();. In your case it would be wise to write overload for scat, like:
public static String scat(Collection<?> vargs) {
StringBuilder sb = new StringBuilder();
for (Object str : vargs)
sb.append(str);
return sb.toString();
}
Then you can call it with:
result = scat(myList)
The compiler can optimize some thing such as
"foo"+"bar"
To
StringBuilder s1=new StringBuilder();
s1.append("foo").append("bar");
However this is still suboptimal since it starts with a default size of 16. As with many things though you should find your biggest bottle necks and work your way down the list. It doesn't hurt to be in the habbit of using a SB pattern from the get go though, especially if you're able to calculate an optimal initialization size.
Premature optimization can be bad as well as it often reduces readability and is usually completely unnecessary. Use + if it is more readable unless you actually have an overriding concern.
It is not 'always bad' to use "+". Using StringBuffer everywhere can make code really bulky.
If someone put a lot of "+" in the middle of an intensive, time-critical loop, I'd be annoyed. If someone put a lot of "+" in a rarely-used piece of code I would not care.
I would say use plus in the following:
String c = "a" + "b"
And use StringBuilder class everywhere else.
As already mentioned in the first case it will be optimized by the compiler and it's more readable.
One of the reasons why FindBugs should argue about using concatenation operator (be it "+" or "+=") is localizability. In the example you gave it is not so apparent, but in case of the following code it is:
String result = "Scanning found " + Integer.toString(numberOfViruses) + " viruses";
If this looks somewhat familiar, you need to change your coding style. The problem is, it will sound great in English, but it could be a nightmare for translators. That's just because you cannot guarantee that order of the sentence will still be the same after translation – some languages will be translated to "1 blah blah", some to "blah blah 3". In such cases you should always use MessageFormat.format() to build compound sentences and using concatenation operator is clearly internationalization bug.
BTW. I put another i18n defect here, could you spot it?
The running time of concatenation of two strings is proportional to the length of the strings. If it is used in a loop running time is always increasing. So if concatenation is needed in a loop its better to use StringBuilder like Anthony suggested.
I am trying to concatenate strings in Java. Why isn't this working?
public class StackOverflowTest {
public static void main(String args[]) {
int theNumber = 42;
System.out.println("Your number is " . theNumber . "!");
}
}
You can concatenate Strings using the + operator:
System.out.println("Your number is " + theNumber + "!");
theNumber is implicitly converted to the String "42".
The concatenation operator in java is +, not .
Read this (including all subsections) before you start. Try to stop thinking the php way ;)
To broaden your view on using strings in Java - the + operator for strings is actually transformed (by the compiler) into something similar to:
new StringBuilder().append("firstString").append("secondString").toString()
There are two basic answers to this question:
[simple] Use the + operator (string concatenation). "your number is" + theNumber + "!" (as noted elsewhere)
[less simple]: Use StringBuilder (or StringBuffer).
StringBuilder value;
value.append("your number is");
value.append(theNumber);
value.append("!");
value.toString();
I recommend against stacking operations like this:
new StringBuilder().append("I").append("like to write").append("confusing code");
Edit: starting in java 5 the string concatenation operator is translated into StringBuilder calls by the compiler. Because of this, both methods above are equal.
Note: Spaceisavaluablecommodity,asthissentancedemonstrates.
Caveat: Example 1 below generates multiple StringBuilder instances and is less efficient than example 2 below
Example 1
String Blam = one + two;
Blam += three + four;
Blam += five + six;
Example 2
String Blam = one + two + three + four + five + six;
Out of the box you have 3 ways to inject the value of a variable into a String as you try to achieve:
1. The simplest way
You can simply use the operator + between a String and any object or primitive type, it will automatically concatenate the String and
In case of an object, the value of String.valueOf(obj) corresponding to the String "null" if obj is null otherwise the value of obj.toString().
In case of a primitive type, the equivalent of String.valueOf(<primitive-type>).
Example with a non null object:
Integer theNumber = 42;
System.out.println("Your number is " + theNumber + "!");
Output:
Your number is 42!
Example with a null object:
Integer theNumber = null;
System.out.println("Your number is " + theNumber + "!");
Output:
Your number is null!
Example with a primitive type:
int theNumber = 42;
System.out.println("Your number is " + theNumber + "!");
Output:
Your number is 42!
2. The explicit way and potentially the most efficient one
You can use StringBuilder (or StringBuffer the thread-safe outdated counterpart) to build your String using the append methods.
Example:
int theNumber = 42;
StringBuilder buffer = new StringBuilder()
.append("Your number is ").append(theNumber).append('!');
System.out.println(buffer.toString()); // or simply System.out.println(buffer)
Output:
Your number is 42!
Behind the scene, this is actually how recent java compilers convert all the String concatenations done with the operator +, the only difference with the previous way is that you have the full control.
Indeed, the compilers will use the default constructor so the default capacity (16) as they have no idea what would be the final length of the String to build, which means that if the final length is greater than 16, the capacity will be necessarily extended which has price in term of performances.
So if you know in advance that the size of your final String will be greater than 16, it will be much more efficient to use this approach to provide a better initial capacity. For instance, in our example we create a String whose length is greater than 16, so for better performances it should be rewritten as next:
Example optimized :
int theNumber = 42;
StringBuilder buffer = new StringBuilder(18)
.append("Your number is ").append(theNumber).append('!');
System.out.println(buffer)
Output:
Your number is 42!
3. The most readable way
You can use the methods String.format(locale, format, args) or String.format(format, args) that both rely on a Formatter to build your String. This allows you to specify the format of your final String by using place holders that will be replaced by the value of the arguments.
Example:
int theNumber = 42;
System.out.println(String.format("Your number is %d!", theNumber));
// Or if we need to print only we can use printf
System.out.printf("Your number is still %d with printf!%n", theNumber);
Output:
Your number is 42!
Your number is still 42 with printf!
The most interesting aspect with this approach is the fact that we have a clear idea of what will be the final String because it is much more easy to read so it is much more easy to maintain.
The java 8 way:
StringJoiner sj1 = new StringJoiner(", ");
String joined = sj1.add("one").add("two").toString();
// one, two
System.out.println(joined);
StringJoiner sj2 = new StringJoiner(", ","{", "}");
String joined2 = sj2.add("Jake").add("John").add("Carl").toString();
// {Jake, John, Carl}
System.out.println(joined2);
You must be a PHP programmer.
Use a + sign.
System.out.println("Your number is " + theNumber + "!");
"+" instead of "."
Use + for string concatenation.
"Your number is " + theNumber + "!"
This should work
public class StackOverflowTest
{
public static void main(String args[])
{
int theNumber = 42;
System.out.println("Your number is " + theNumber + "!");
}
}
For exact concatenation operation of two string please use:
file_names = file_names.concat(file_names1);
In your case use + instead of .
For better performance use str1.concat(str2) where str1 and str2 are string variables.
String.join( delimiter , stringA , stringB , … )
As of Java 8 and later, we can use String.join.
Caveat: You must pass all String or CharSequence objects. So your int variable 42 does not work directly. One alternative is using an object rather than primitive, and then calling toString.
Integer theNumber = 42;
String output =
String // `String` class in Java 8 and later gained the new `join` method.
.join( // Static method on the `String` class.
"" , // Delimiter.
"Your number is " , theNumber.toString() , "!" ) ; // A series of `String` or `CharSequence` objects that you want to join.
) // Returns a `String` object of all the objects joined together separated by the delimiter.
;
Dump to console.
System.out.println( output ) ;
See this code run live at IdeOne.com.
In java concatenate symbol is "+".
If you are trying to concatenate two or three strings while using jdbc then use this:
String u = t1.getString();
String v = t2.getString();
String w = t3.getString();
String X = u + "" + v + "" + w;
st.setString(1, X);
Here "" is used for space only.
In Java, the concatenation symbol is "+", not ".".
"+" not "."
But be careful with String concatenation. Here's a link introducing some thoughts from IBM DeveloperWorks.
You can concatenate Strings using the + operator:
String a="hello ";
String b="world.";
System.out.println(a+b);
Output:
hello world.
That's it
So from the able answer's you might have got the answer for why your snippet is not working. Now I'll add my suggestions on how to do it effectively. This article is a good place where the author speaks about different way to concatenate the string and also given the time comparison results between various results.
Different ways by which Strings could be concatenated in Java
By using + operator (20 + "")
By using concat method in String class
Using StringBuffer
By using StringBuilder
Method 1:
This is a non-recommended way of doing. Why? When you use it with integers and characters you should be explicitly very conscious of transforming the integer to toString() before appending the string or else it would treat the characters to ASCI int's and would perform addition on the top.
String temp = "" + 200 + 'B';
//This is translated internally into,
new StringBuilder().append( "" ).append( 200 ).append('B').toString();
Method 2:
This is the inner concat method's implementation
public String concat(String str) {
int olen = str.length();
if (olen == 0) {
return this;
}
if (coder() == str.coder()) {
byte[] val = this.value;
byte[] oval = str.value;
int len = val.length + oval.length;
byte[] buf = Arrays.copyOf(val, len);
System.arraycopy(oval, 0, buf, val.length, oval.length);
return new String(buf, coder);
}
int len = length();
byte[] buf = StringUTF16.newBytesFor(len + olen);
getBytes(buf, 0, UTF16);
str.getBytes(buf, len, UTF16);
return new String(buf, UTF16);
}
This creates a new buffer each time and copies the old content to the newly allocated buffer. So, this is would be too slow when you do it on more Strings.
Method 3:
This is thread safe and comparatively fast compared to (1) and (2). This uses StringBuilder internally and when it allocates new memory for the buffer (say it's current size is 10) it would increment it's 2*size + 2 (which is 22). So when the array becomes bigger and bigger this would really perform better as it need not allocate buffer size each and every time for every append call.
private int newCapacity(int minCapacity) {
// overflow-conscious code
int oldCapacity = value.length >> coder;
int newCapacity = (oldCapacity << 1) + 2;
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
int SAFE_BOUND = MAX_ARRAY_SIZE >> coder;
return (newCapacity <= 0 || SAFE_BOUND - newCapacity < 0)
? hugeCapacity(minCapacity)
: newCapacity;
}
private int hugeCapacity(int minCapacity) {
int SAFE_BOUND = MAX_ARRAY_SIZE >> coder;
int UNSAFE_BOUND = Integer.MAX_VALUE >> coder;
if (UNSAFE_BOUND - minCapacity < 0) { // overflow
throw new OutOfMemoryError();
}
return (minCapacity > SAFE_BOUND)
? minCapacity : SAFE_BOUND;
}
Method 4
StringBuilder would be the fastest one for String concatenation since it's not thread safe. Unless you are very sure that your class which uses this is single ton I would highly recommend not to use this one.
In short, use StringBuffer until you are not sure that your code could be used by multiple threads. If you are damn sure, that your class is singleton then go ahead with StringBuilder for concatenation.
First method: You could use "+" sign for concatenating strings, but this always happens in print.
Another way: The String class includes a method for concatenating two strings: string1.concat(string2);
import com.google.common.base.Joiner;
String delimiter = "";
Joiner.on(delimiter).join(Lists.newArrayList("Your number is ", 47, "!"));
This may be overkill to answer the op's question, but it is good to know about for more complex join operations. This stackoverflow question ranks highly in general google searches in this area, so good to know.
you can use stringbuffer, stringbuilder, and as everyone before me mentioned, "+". I'm not sure how fast "+" is (I think it is the fastest for shorter strings), but for longer I think builder and buffer are about equal (builder is slightly faster because it's not synchronized).
here is an example to read and concatenate 2 string without using 3rd variable:
public class Demo {
public static void main(String args[]) throws Exception {
InputStreamReader r=new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(r);
System.out.println("enter your first string");
String str1 = br.readLine();
System.out.println("enter your second string");
String str2 = br.readLine();
System.out.println("concatenated string is:" + str1 + str2);
}
}
There are multiple ways to do so, but Oracle and IBM say that using +, is a bad practice, because essentially every time you concatenate String, you end up creating additional objects in memory. It will utilize extra space in JVM, and your program may be out of space, or slow down.
Using StringBuilder or StringBuffer is best way to go with it. Please look at Nicolas Fillato's comment above for example related to StringBuffer.
String first = "I eat"; String second = "all the rats.";
System.out.println(first+second);
Using "+" symbol u can concatenate strings.
String a="I";
String b="Love.";
String c="Java.";
System.out.println(a+b+c);
StringBuffer or HashMap
Which is the best way to append codes and also makes performance better.
StringBuffer sql = new StringBuffer();
DBDatabase db = UTIL.getDatabase();
sql.append("SELECT I.FLDCODE, I.FLDDESCR, I.FLDWORKPHON FROM ");
sql.append(db.getSchema());
sql.append("TRNINSTR I, ");
sql.append(db.getSchema());
sql.append("TRNCRSIN C WHERE C.FLDCOURSE = ? AND C.FLDINSTRUCT = I.FLDCODE AND (I.FLDINACTIVE IS NULL OR I.FLDINACTIVE <> 'y') ORDER BY C.FLDSEQUENCE");
DBPreparedStatement stmt = new DBPreparedStatement(db, sql, "TrainPage.getInfoInstrList");
stmt.setString(1, courseType);
DBResultSet rs = stmt.executeQuery();
stmt.close();
StringBuilder performs even better. Bear in mind that the slow part is database access not statement preparation.
Your question is unclear ("appending codes"? "HashMap"?), but I'll assume that you are asking what is the more efficient way to build a String.
In general, a StringBuilder is more efficient than a StringBuffer, because the latter's methods are synchronized and this is just an unnecessary overhead for a thread-confined object.
But then there is the question of whether using a StringBuilder is more efficient than simple String concatenation. And the answer to that is that "it depends".
If you are doing lots of separate concatenations, then a StringBuilder is typically faster; e.g.
String s = "";
for (int i = 0; i < 1000; i++) {
s += "X";
}
If you are doing all of the concatenations in one expression, then it probably makes no difference:
String s = "Hi " + name + ". It is a might fine " + day + ".";
This is because the Java compiler will turn that into code that creates a StringBuilder and performs a series of append calls.
However, that is a slight over-simplification. On the one hand, if your application can easily calculate the length of the final String, you can get somewhat better performance using a StringBuilder by allocating the builder with the right initial capacity. On the other hand, the compiler will evaluate concatenations of String literals before hand, so
String s = "Hi " + "mom" + ". is a might fine " + "tuesday" + ".";
will be faster than:
StringBuilder sb = new StringBuilder();
sb.append("Hi ");
sb.append("mom");
sb.append(". is a might fine ");
sb.append("tuesday");
sb.append(".");
String s = sb.toString();
But the bottom line is that it probably doesn't matter. Unless you do a huge amount of string building, the chances are that the impact on the overall performance of your application will be minimal.
I read a lot about using StringBuffer and String especially where concatenation is concerned in Java and whether one is thread safe or not.
So, in various Java methods, which should be used?
For example, in a PreparedStatement, should query be a StringBuffer:
String query = ("SELECT * " +
"FROM User " +
"WHERE userName = ?;");
try {
ps = connection.prepareStatement(query);
And then again, in a String utility methods like:
public static String prefixApostrophesWithBackslash(String stringIn) {
String stringOut = stringIn.replaceAll("'", "\\\\'");
return stringOut;
}
And:
// Removes a char from a String.
public static String removeChar(String stringIn, char c) {
String stringOut = ("");
for (int i = 0; i < stringIn.length(); i++) {
if (stringIn.charAt(i) != c) {
stringOut += stringIn.charAt(i);
}
}
return stringOut;
}
Should I be using StringBuffers? Especially where repalceAll is not available for such objects anyway.
Thanks
Mr Morgan.
Thanks for all the advice. StringBuffers have been replaced with StringBuilders and Strings replaced with StringBuilders where I've thought it best.
You almost never need to use StringBuffer.
Instead of StringBuffer you probably mean StringBuilder. A StringBuffer is like a StringBuilder except that it also offers thread safety. This thread safety is rarely needed in practice and will just cause your code to run more slowly.
Your question doesn't seem to be about String vs StringBuffer, but about using built-in methods or implementing the code yourself. If there is a built-in method that does exactly what you want, you should probably use it. The chances are it is much better optimized than the code you would write.
There is no simple answer (apart from repeating the mantra of StringBuilder versus StringBuffer ... ). You really have understand a fair bit about what goes on "under the hood" in order to pick the most efficient solution.
In your first example, String is the way to go. The Java compiler can generate pretty much optimal code (using a StringBuilder if necessary) for any expression consisting of a sequence of String concatenations. And, if the strings that are concatenated are all constants or literals, the compiler can actually do the concatenation at compile time.
In your second example, it is not entirely clear whether String or StringBuilder would be better ... or whether they would be roughly equivalent. One would need to look at the code of the java.util.regex.Matcher class to figure this out.
EDIT - I looked at the code, and actually it makes little difference whether you use a String or StringBuilder as the source. Internally the Matcher.replaceAll method creates a new StringBuilder and fills it by appending chunks from the source String and the replacement String.
In your third example, a StringBuilder would clearly be best. A current generation Java compiler is not able to optimize the code (as written) to avoid creating a new String as each character is added.
For the below segment of code
// Removes a char from a String.
public static String removeChar(String stringIn, char c) {
String stringOut = ("");
for (int i = 0; i < stringIn.length(); i++) {
if (stringIn.charAt(i) != c) {
stringOut += stringIn.charAt(i);
}
}
return stringOut;
}
You could just do stringIn.replaceAll(c+"","")
Even in MT code, it's unusual to have multiple threads append stuff to a string. StringBuilder is almost always preferred to StringBuffer.
Modern compilers optimize the code already. So some String additions will be optimized to use StringBuilder and we can keep the String additions if we think, it increases readibility.
Example 1:
String query = ("SELECT * " +
"FROM User " +
"WHERE userName = ?;");
will be optimized to somthing like:
StringBuiler sb = new StringBuilder();
sb.append("SELECT * ");
sb.append("FROM User ");
sb.append("WHERE userName = ?;");
String query = sb.toString();
Example 2:
String numbers = "";
for (int i = 0;i < 20; i++)
numbers = numbers + i;
This can't be optimized and we should use a StringBuilder in code.
I made this observation for SUN jdk1.5+. So for older Java versions or different jdks it can be different. There it could be save to always code StringBuilder (or StringBuffer for jdk 1.4.2 and older).
For cases which can be considered single threaded, the best would be StringBuilder. It does not add any synchronization overhead, while StringBuffer does.
String concatenation by '+' operator is "good" only when you're lazy to use StringBuilder or just want to keep the code easily readable and it is acceptable from performance point of view, like in startup log message "LOG.info("Starting instance " + inst_id + " of " + app_name);"