Is conversion to String in Java using
"" + <int value>
bad practice? Does it have any drawbacks compared to String.valueOf(...)?
Code example:
int i = 25;
return "" + i;
vs:
int i = 25;
return String.valueOf(i);
Update: (from comment)
And what about Integer.toString(int i) compared to String.valueOf(...)?
I would always prefer the String.valueOf version: mostly because it shows what you're trying to do. The aim isn't string concatenation - it's conversion to a string, "the string value of i".
The first form may also be inefficient - depending on whether the compiler spots what you're doing. If it doesn't, it may be creating a new StringBuffer or StringBuilder and appending the value, then converting it to a string.
Funnily enough, I have an article about this very topic - written years and years ago; one of the first Java articles on my web site, IIRC.
There is also Integer.toString(int i), which gives you the option of getting the string as a hex value as well (by passing a second param of 16).
Edit I just checked the source of String class:
public static String valueOf(int i) {
return Integer.toString(i, 10);
}
And Integer class:
public static String toString(int i, int radix) {
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
radix = 10;
/* Use the faster version */
if (radix == 10) {
return toString(i);
}
...
If you call String.valueOf(i), it calls Integer.toString(i, 10), which then calls Integer.toString(i).
So Integer.toString(i) should be very slighty faster than String.valueOf(i), since you'd be cutting out two function calls. (Although the first function call could be optimized away by the compiler.)
Of course, a readability argument could still be made for String.valueOf(), since it allows you to change the type of the argument (and even handles nulls!), and the performance difference is negligible.
Definitely use String.valueOf(i).
Although I'm not sure of the optimizations on the compiler side, worst case scenario if you use "" + :
"" creates a new empty string.
"" + creates a StringBuilder (Java 1.5-16)
"" is appended to the StringBuilder, then
In other words, there is a lot of overhead that occurs if you use string addition. This is why it is not recommended to use the + operator on strings in loops. In general, always use Boolean.valueOf, Integer.valueOf, String.valueOf... etc, when possible. You'll save both on memory and on overhead.
Regardless of any performance considerations I think the first variant is really ugly. IMHO it's a shame that this kind of "dynamic casting" is even possible in Java.
Yes, it is IMHO a bad practice.
It would require to memory allocations (unless compiler and/or JIT optimize them). What's more, it will make less evident, what this code tries to do.
Personally I dislike the style of "" + i, but that is really a preference/coding standards thing. Ideally the compiler would optimize those into equivalent code (although you would have to decompile to see if it actually does), but technically, without optimization, "" + i is more inefficient because it creates a StringBuilder object that wasn't needed.
Right off the bat all I can think of is that in the your first example more String objects will be created than in the second example (and an additional StringBuilder to actually perform the concatenation).
But what you are actualy trying to do is create a String object from a int not concatenate a String with an int, so go for the:
String.valueOf(...);
option,
So yes your first option is bad practice!
I wonder what is best for static final variables contributing to compile-time constants:
public static final int VIEW_TYPE_LABEL_FIELD = 1;
public static final int VIEW_TYPE_HEADER_FIELD = ;
...
List <String[]> listViewInfo = new ArrayList<>();
listViewInfo.add(new String[]{"Label/Field view", String.valueOf(VIEW_TYPE_LABEL_FIELD)});
listViewInfo.add(new String[]{"Header/Field view", "" + VIEW_TYPE_LABEL_FIELD});
The compiler can potentially replace the String expressions with a constant. Is one or the other more recognizable as a compile-time constant? Maybe easier for the ("" + ..) construct?
Related
I am currently using
Double a = 0.00;
for(condition)
//Do things
String result = "" + a;
Would using
String result = a.toString();
Provide any real benefit compared to what I have now. Does this just help the compiler or are there any differences between the two methods?
The first version - String result = "" + a under the hood is the same as String result = "" + a.toString();. Whenever there is a concatenation of String + Object the toString method is called.
What is the best practice here? What looks better for you. I'd probably go with the first version.
If you're concerned about the performance of both - String result = a.toString(); on paper will be faster because you don't need to create / get an empty String just to create a new one. However, as with many things in Java, something like that most likely gets optimized by JIT compiler anyway so I wouldn't worry about it too much. Even if it doesn't you shouldn't worry about optimization prematurely - if your code runs slowly then usually there is something else wrong with it that is much bigger than that.
I think second option is better because concatenation of strings cost much more memory.Since Strings are immutable objects in the first way your memory is wasting for store a Double object + two String Objects .
But in the second option it only create one new String object only .So in your memory there will only be one Double object + one String Object.
This question already has answers here:
String valueOf vs concatenation with empty string
(10 answers)
Closed 7 years ago.
I've had a few people tell me that things like this are super lazy:
int val = 5;
System.out.println("" + val);
String myStr = "" + val;
Why is this better than String.valueOf(val)? Isn't it doing the exact same thing under the hood?
It's not really "better", just shorter, making it easier to read and type. There is (virtually) no ther difference, even though a real purist might, probably, say, this is actually worse, because (at least, in the absence of optimization), this creates an intermediate StringBuilder object, that is then appended a character before being converted into a String, so, this may be spending more ticks, than .valueOf.
From JLS:
An implementation may choose to perform conversion and concatenation in one step to avoid creating and then discarding an intermediate String object. To increase the performance of repeated string concatenation, a Java compiler may use the StringBuffer class or a similar technique to reduce the number of intermediate String objects that are created by evaluation of an expression.
For primitive types, an implementation may also optimize away the creation of a wrapper object by converting directly from a primitive type to a string.
This question already has answers here:
StringBuilder vs String concatenation in toString() in Java
(20 answers)
String concatenation in Java - when to use +, StringBuilder and concat [duplicate]
(9 answers)
Closed 8 years ago.
As I understand it, when I do String baz = "foo" + "bar" + "123" the Java compiler internally replaces the expression with a StringBuilder. However our Java teacher told us that it is good practice to always use a StringBuilder explicitly...
Am I correct in assuming I will only need to explicitly use StringBuilder when concatenating inside loops as indicated in an answer to Stack Overflow question String builder vs string concatenation? Are there other cases where you should explicitly use a StringBuilder instead of + or +=?
It's more general than "inside loops" - it's any time you want to do concatenation over multiple statements, and don't need the intermediate result as a string. For example:
StringBuilder builder = new StringBuilder("Start");
if (someCondition) {
builder.append("Foo");
}
if (someOtherCondition) {
builder.append("Bar");
}
builder.append("End");
String result = builder.toString();
While you could write that as:
String result = "Start" + (someCondition ? "Foo" : "")
+ (someOtherCondition ? "Bar" : "") + "End";
... that becomes hard to read. And if there are more statements within the if bodies, it may not even be feasible.
To correct something within your question though:
As I understand it, when I do String baz = "foo" + "bar" + "123" the java compiler internally replaces the expression with a StringBuilder.
No, when you write that expression the compiler recognizes that it's a compile-time constant, and replaces it with
String baz = "foobar123";
That's a very good reason not to explicitly use a StringBuilder - the code above is clearly more efficient at execution time than
String baz = new StringBuilder("foo").append("bar").append("123").toString();
When it isn't a compile-time constant, the Java compiler will perform the concatenation using a StringBuilder, usually leaving you with easier-to-understand code than with the explicit use of StringBuilder, but with no performance hit. I suspect your teacher either doesn't properly understand string concatenation, or simply read somewhere else that you should use StringBuilder without fully understanding when it's appropriate.
Obi Wan has said that only Sith thinks in absolutes or something similar...
It's good you know that Java compiler internally replaces "+" on Strings with the usage of the StringBuilder. This is what are the compilers for: to make the life easier.
Unless you have loops, as in linked case, or conditionals from Jon Skeet's example, it's primarily the matter of readibility and the ease of maintanance.
Replacing
return "User " + userName + " said";
with
new StringBuilder().append("User ").append(userName).append(" said").toString();
makes the code longer, probably harder to modify, is more likely to force line breaks, and gives you more performance.
However, when the addition apply not only to the strings, but there are numbers involved, probably the solution with StringBuilder sometimes may be more readable.
return "User" + a + b + " said: " + (c + d);
may be more confusing as:
return new StringBuilder().append("User ").append(a).append(b)
.append(" said: ").append(c+d).toString();
But it's primarily the matter of opinion and coding style. "Should" is not a good word here.
They're also good for implementing things like C#'s 'out' keyword with a String. Example
public int getInt(StringBuilder error)
{
int retVal = 0;
if (someErrorOccured)
error.append("Couldn't get int because of...");
else
retVal = whatItsSupposedToBe;
return retVal;
}
What is the style recommendation for the Java string concatenation operator "+"?
Edit: Specifically, should it be used or not?
Thinking in Java (Eckel) says that the overloaded + operator is implemented using StringBuilder (although not all compilers may be supporting this as per alphazero's answer) and thus multiple String objects and the associated memory use and garbage collection are avoided. Given this, I would answer my own question by saying that the + operator is probably fine, style-wise. The only caveat is that the + is the only instance of overloading in the language and that exceptionalism might count as a minor reason not to use it. In retrospect, the advantage of terseness is pretty significant in some situations and that has got to count for a lot of style.
As long as your team members are comfortable with it.
Because there is no "correct" coding style. But I agree that you should always use white-spaces between strings and operator for better readability.
Following Java's coding conventions Strings should be concatenated like:
String str = "Long text line "
+ "more long text.";
Make sure the '+' operator always begins the next line.
https://www.oracle.com/technetwork/java/javase/documentation/codeconventions-136091.html#248
It is perfectly fine to use the '+' operator for String concatenation, there are different libraries that provide other structure for it, but for me it is the most simple way.
Hope this helps!
Happy coding,
Brady
Is this what you meant?
"string1" + "string"
or, if you have long lines
"a really long string....." +
"another really long string......" +
"ditto once again" +
"the last one, I promise"
If you have the time to format this right, then:
"a really long string....." +
"another really long string......" +
"ditto once again" +
"the last one, I promise"
Basically, every time you use the + operator, you should use it with at least one whitespace before and after. If you're using it when concatenating long strings, put it at the end of the line.
The overall recommendation is not to use this form (at all) if performance is of concern, and to instead use StringBuilder or StringBuffer (per your threading model). The reason is simply this: Strings in java are immutable and the '+' operator will create many intermediary String objects when processing expressions of form S1 + S2 + ... + Sn.
[Edit: Optimization of String Concatenation]
In my project there are some code snippets which uses StringBuffer objects, and the small part of it is as follows
StringBuffer str = new StringBuffer();
str.append("new " + "String()");
so i was confused with the use of append method and the + operator.
ie the following code could be written as
str.append("new ").append("String()");
So are the two lines above same?(functionally yes but) Or is there any particular usage of them? ie performance or readability or ???
thanks.
In that case it's more efficient to use the first form - because the compiler will convert it to:
StringBuffer str = new StringBuffer();
str.append("new String()");
because it concatenates constants.
A few more general points though:
If either of those expressions wasn't a constant, you'd be better off (performance-wise) with the two calls to append, to avoid creating an intermediate string for no reason
If you're using a recent version of Java, StringBuilder is generally preferred
If you're immediately going to append a string (and you know what it is at construction time), you can pass it to the constructor
Actually the bytecode compiler will replace all string concatenation which involve non constants in a Java program with invocations of StringBuffer. That is
int userCount = 2;
System.out.println("You are the " + userCount + " user");
will be rewritten as
int userCount = 2;
System.out.println(new StringBuffer().append("You are the ").append(userCount).append(" user").toString());
That is at least what is observable when decompiling java class files compiled with JDK 5 or 6. See this post.
The second form is most efficient in terms of performance because there is only one string object that is created and is appended to the stringbuffer.
The first form creates three string objects 1) for "new" 2)for "new String" 3) for the concatenated result of 1) and 2). and this third string object is concatenated to the string buffer.
Unless you are working with concurrent systems, use StringBuilder instead of StringBuffer. Its faster but not thread-safe :)
It also shares the same API so its more or less a straight find/replace-