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);
Related
I am aware that we can use String Utils library. But what if the String has only "0". It returns " ". Do we have any other way to remove leading 0 for all other strings except for "0".
Here is the scenario:
So, I am truncating the value of the Strings that are being entered by the users on the client side.All the inputs are taken in form of strings. For example if the user enters the department number as 009, I will truncate it to 9. For 08 it should be 8. But , here there is a department with 0. So when user is entering only 0, this method removes 0 too
Also what if the input is 000. I need last 0 with out being truncated.
I am aware that we can use String Utils library. But what if the String has only "0". It returns " ". Do we have any other way to remove leading 0 for all other strings except for "0".
You can create your own utility method that does exactly what you want.
Well you still haven't answered my question about whether the department can be alphanumeric or just numeric.
Based on your examples you could just convert the String to an Integer. The toString() implementation of an Integer removes leading zeroes:
System.out.println( new Integer("008").toString() );
System.out.println( new Integer("000").toString() );
System.out.println( new Integer("111").toString() );
If the string can contain alphanumeric the logic would be more complex, which is why it is important to define the input completely.
For an alphanumeric string you could do something like:
StringBuilder sb = new StringBuilder("0000");
while (sb.charAt(0) == '0' && sb.length() > 1)
sb.deleteCharAt(0);
System.out.println(sb);
Or, an even more efficient implementation would be something like:
int i = 0;
while (product.charAt(i) == '0' && i < product.length() - 1)
i++;
System.out.println( product.substring(i) );
The above two solutions are the better choice since they will work for numeric and alphanumeric strings.
Or you could even use the StringUtils class to do what you want:
String result = StringUtils.removeleadingZeroes(...) // whatever the method is
if (result.equals(" "))
result = "0";
return result;
In all solutions you would create a method that you pass parameter to and then return the String result.
If you want to use a regex based approach, then one option would be to greedily remove all zeroes, starting from the beginning, so long as we do not replace the final character in the string. The following pattern does this:
^0+(?=.)
The lookahead ensures that there is at least one digit remaining, hence, a final zero will never be replaced.
String input1 = "040008";
String input2 = "000008";
String input3 = "000000";
input1 = input1.replaceAll("^0+(?=.)", "");
input2 = input2.replaceAll("^0+(?=.)", "");
input3 = input3.replaceAll("^0+(?=.)", "");
System.out.println(input1);
System.out.println(input2);
System.out.println(input3);
40008
8
0
Demo
By the way, I like the answer by #camickr and you should consider that as an option.
I'm trying to create a string comprised of a single letter, followed by 4 digits e.g. b6789. I'm getting stuck when I try to convert a character, and integer to one String. I can't use toString() because I've overwritten it, and I assume that concatenation is not the best way to approach it? This was my solution, until I realised that valueof() only takes a single parameter. Any suggestions? FYI - I'm using Random, because I will be creating multiples at some point. The rest of my code seemed irrelevant, and hence has been omitted.
Random r = new Random();
Integer numbers = r.nextInt(9000) + 1000;
Character letter = (char)(r.nextInt(26) + 'a');
String strRep = String.valueOf(letter, numbers);
I think they mean for you not to use concatenation with + operator.
Rather than that, there's a class called StringBuilder which will do the trick for you. Just create an empty one, append anything you need on it (takes Objects or primitives as arguments and does all the work for you), and at the end, just call at its "toString()" method, and you'll have your concatenated String.
For example
StringBuilder sb = new StringBuilder();
sb.append("Foo");
sb.append(123);
return sb.toString();
would return the string Foo123
you can use:
Character.toString(char)
which is
String.valueOf(char)
in reality which also works.
or just use
String str = "" + 'a';
as already mentioned but not very efficient as it is
String str = new StringBuilder().append("").append('a').toString();
in reality.
same goes for integer + string or char + int to string. I think your simpliest way would be to use string concatenation
Looks like you want
String.valueOf(letter).concat(numbers.toString());
I have the following class:
public class Go {
public static void main(String args[]) {
System.out.println("G" + "o");
System.out.println('G' + 'o');
}
}
And this is compile result;
Go
182
Why my output contain a number?
In the second case it adds the unicode codes of the two characters (G - 71 and o - 111) and prints the sum. This is because char is considered as a numeric type, so the + operator is the usual summation in this case.
+ operator with character constant 'G' + 'o' prints addition of charCode and string concatenation operator with "G" + "o" will prints Go.
The plus in Java adds two numbers, unless one of the summands is a String, in which case it does string concatenation.
In your second case, you don't have Strings (you have char, and their Unicode code points will be added).
System.out.println("G" + "o");
System.out.println('G' + 'o');
First one + is acted as a concat operater and concat the two strings. But in 2nd case it acts as an addition operator and adds the ASCII (or you cane say UNICODE) values of those two characters.
This previous SO question should shed some light on the subject, in your case you basically end up adding their ASCII values (71 for G) + (111 for o) = 182, you can check the values here).
You will have to use the String.valueOf(char c) to convert that character back to a string.
The "+" operator is defined for both int and String:
int + int = int
String + String = String
When adding char + char, the best match will be :
(char->int) + (char->int) = int
But ""+'a'+'b' will give you ab:
( (String) + (char->String) ) + (char->String) = String
+ is always use for sum(purpose of adding two numbers) if it's number except String and if it is String then use for concatenation purpose of two String.
and we know that char in java is always represent a numeric.
that's why in your case it actually computes the sum of two numbers as (71+111)=182 and not concatenation of characters as g+o=go
If you change one of them as String then it'll concatenate the two
such as System.out.println('G' + "o")
it will print Go as you expect.
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.
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.