Primitive + "" versus Wrapper.toString(primitive) - java

When needing to convert a primitive to a String, for example to pass to a method that expects a String, there are basically two options.
Using int as an example, given:
int i;
We can do one of:
someStringMethod(Integer.toString(i));
someStringMethod(i + "");
The first one is the "formal" approach, and the second one seems somewhat of a "hack".
It's certainly a lot less code and easier to read the "hack" IMHO.
But is it "good" coding style to use the "hack"?

The best way to convert * to String is to use:
String.valueOf(x)
it works with primitive types, wrapper classes and Object who do implement toString().
where x is any kind of primitive or object. If it is null it returns the string 'null'.
The reason why this is best, is because using "+" operand implies String concatenation, plus the "" implies String instantiation. If you decompile a class using ""+something you'll see the compiler translate that to multiple operations.
"" concatenation result is the same as String.valueOf() but it is a little bit more expensive.
The performance difference is probably negligible, but good programmers don't write '"" + something' to convert something to a String when there is a better way, which happens to be the correct way :).
For arrays, have a look at Arrays.toString() and -better- Arrays.deepToString()
But is it "good" coding style to use the "hack"?
Sometimes syntactic hack make the code better. But the case above, is not really one of those cases.
"" concatenation not considered good code.
An example of a useful syntactic hack is the double brace instantiation:
List<String> list = new ArrayList<String>() {{
add("foo");
add("bar");
add("baz");
}};
instead of
List<String> list = new ArrayList<String>();
list.add("foo");
list.add("bar");
list.add("baz");
The ""+something is more a code smell than a hack that improve readability; anybody with some experience would think to a Java developer who lack some knowledge of the API and the language.
Other interesting "hacks" are fluent APIs (like Mockito), dsl, or things like lambda4j, which is quite an hack.

It's not a good idea, but it's not going to be very harmful.
In both examples Integer.toString() is being called by the JVM (even if not directly in the first case).
In the second example, the JVM possibly constructs two strings and then produces the result of the concatenation. Depending on optimizations this may result in 0, 1 or 2 extra strings to garbage collect.
From a code writing perspective, the third is shorter, but also possibly less transparent as to what is happening.
The problems with the second approach in readability follow:
int i = 1, j = 2;
someStringMethod(i + j + "" + i + j + "");
Produces:
someStringMethod(312);
and not
someStringMethod(33);

When strings are formed using + sign, jvm will create a intermediate string/stringbuffer object to carry out trasnformation, which is not the optimum way.
Also, + sign is left associative,so when used in expressions like ""+1+2 will result in 12 and not "3".So it's better to use String.toValue() or Type.toString().

Concatenation symbol in java is +.
So you convert the result of (i + "") to String because you concat an empty string to a number in your example code.
The two ways are good but I normally use String.valueOf(x);

Related

What's this Java idiom? String constructor with concatenation

In a code base I'm working with I'm seeing this idiom being used.Can someone explain it for me?
new String("" + number) // `i` is an instance of Integer
For some context, this is approximately what the method looks like:
public String someMethod(String numberString) {
Integer number = new Integer(numberString);
// other stuff happens...
return new String("" + number);
}
It's most likely nothing but an inexperienced Java programmers attempt at converting a number to a String.
Whether converting numbers to Strings using "" + number is good practice is debateable. I for one find String.valueOf(number) to be more clear (although it's semantically equivalent).
It's completely unnecessary to wrap the result in new String(...) unless you (for some unimaginable reason) really need a new string, i.e. one that's referentially distinct from other strings.
This ideom is the easiest way of converting any primitive or Object type to a string.
It is quite easy: Typing "" + number is less work than typing String.valueOf(number) (or Integer.toString(number). The latter is the usual way of transforming an int into a String. Which one is clearer and to be preferred is a matter of taste. You will find advocates for both versions.
But note three things:
Calling String.valueOf(number) is faster, because "" + number will become a string concatenation, it will be compiled to
new StringBuilder().append("").append(number).toString()
However, unless this statement is in a hot place in your code, the difference will not matter at all. Even in a hot place, the difference might still be negligible
Simply calling number.toString() is also an option since number is a boxed integer. However, if number is null, this will trigger a null pointer exception so be careful!
The last line of your example, i.e., new String("" + number); is simply crap! It wraps the result into a newly built string. This creates an unnecessary copy and costs precious extra keystrokes. It also generates unnecessary boilerplate noise in your code. This last line compiles to:
new String(new StringBuilder().append("").append(number).toString())
That is quite some work for transforming int to String. You first create a StringBuilder, then a built String and then a copy of this built String. This creates three objects instead of one.
This idiom is used to automatically convert the integer number to a string.
The String constructor expects an argument of type String. The expression new String(number) would not compile. Concatenting an empty string is a little trick to turn the Integer into a String.
You could of course use new String(number.toString()) or String.valueOf(number) instead.
Note: As Jon Skeet mentions in the comments there is no need to use new Sring() at all. You could just return number.toString(); or return String.valueOf(number)

String.format() vs string concatenation performance

is there any difference in performance between these two idioms ?
String firstStr = "Hello ";
String secStr = "world";
String third = firstStr + secStr;
and
String firstStr = "Hello ";
String secStr = "world";
String third = String.format("%s%s",firstStr , secStr);
I know that concatenation with + operator is bad for performance specially if the operation is done a lot of times, but what about String.format() ? is it the same or it can help to improve performance?
The second one will be even slower (if you look at the source code of String.format() you will see why). It is just because String.format() executes much more code than the simple concatenation. And at the end of the day, both code versions create 3 instances of String. There are other reasons, not performance related, to use String.format(), as others already pointed out.
First of all, let me just put a disclaimer against premature optimization. Unless you are reasonably sure this is going to be a hotspot in your program, just choose the construct that fits your program the best.
If you are reasonably sure, however, and want to have good control over the concatenation, just use a StringBuilder directly. That's what the built-in concatenation operation does anyway, and there's no reason to assume that it's slow. As long as you keep the same StringBuilder and keep appending to it, rather than risking creating several in a row (which would have to be "initialized" with the previously created data), you'll have proper O(n) performance. Especially so if you make sure to initialize the StringBuilder with proper capacity.
That also said, however, a StringBuilder is, as mentioned, what the built-in concatenation operation uses anyway, so if you just keep all your concatenations "inline" -- that is, use A + B + C + D, rather than something like e = A + B followed by f = C + D followed by e + f (this way, the same StringBuilder is used and appended to throughout the entire operation) -- then there's no reason to assume it would be slow.
EDIT: In reply to your comment, I'd say that String.format is always slower. Even if it appends optimally, it can't do it any faster than StringBuilder (and therefore also the concatenation operation) does anyway, but it also has to create a Formatter object, do parsing of the input string, and so on. So there's more to it, but it still can't do the basic operation any faster.
Also, if you look internally in how the Formatter works, you'll find that it also (by default) uses a StringBuilder, just as the concatenation operation does. Therefore, it does the exact same basic operation -- that is, feeding a StringBuilder with the strings you give it. It just does it in a far more roundabout way.
As described in this excellent answer , you would rather use String.format, but mainly because of localization concerns.
Suppose that you had to supply different text for different languages, in that case then using String.format - you can just plug in the new languages(using resource files). But concatenation leaves messy code.
See : Is it better practice to use String.format over string Concatenation in Java?

Advantages of format over concatenation

I'm using Java, and I was wondering if there is any advantage to using format over simple concatenation.
I would either format like this:
a = String.format("%s/hi", b);
or like this:
a = (b + "/hi");
Is there any advantage (other than cleanliness) of using one over the other?
It is better practice to use String.format over String.concat.
String.format() is more than just concatenating strings. For example, you can display numbers is a specific locale using String.format().
However, if you don't care about localization, functionally, there is no difference. Maybe one is faster than the other, but in most cases it will be negligible.
Format can handle quite complex patterns and formatting, if you need them. I would personally go for readability over any perceived "performance" benefits for anything other than code used in a large loop. Who cares if your method creates a couple of objects that get garbage collected soon afterwards anyway?
Only one String will be created in the following line,
a = String.format("%s/hi", b);
More than One String is being created in the following line
a = (b + "/hi");

difference between String.valueOf(int) , `+` string operator and Integer.toString(int)

Not confident about whether this will be downvoted or closed... I need expert opinion on this.
The context is in our application, we have written code like :
//countryId is an integer, searchCity() expects two String parameters
loadCity(countryName , countryId + "");
Will it make any difference if I change (I am being forced to do so) the call like :
loadCity(countryName, String.valueOf(countryId));
Or,
loadCity(countryName, Integer.toString(countryId));
Will this make any difference in sense of performance?
For the example you have given, the answer will really depend on the type of 'integer' you are using.
loadCity(countryName , countryId + "");
For an Integer object this is equivelent to :
loadCity(countryName, countryId.toString() + "");
Whereas for an int primitive, this code is equivelent to :
loadCity(countryName, String.valueOf(countryId) + "");
In either case, as ArjunShankar pointed out there is a good chance that the compiler has optimised your code anyway. So if your question is 'do I go back and refactor all my code?', then I would say 'don't sweat the small stuff'. But in the future use a more conventional approach to avoid the down votes.
I'd say the main difference is readability. There's no use in micro-benching here. IMHO String#valueOf reads the best.
From the docs of String.valueOf
"The representation is exactly the one returned by the Integer.toString method of one argument."
I would use String.valueOf because you can use it on more then just Integers, i.e. you don't have to know whether you have an int, double, bool, etc....
They are same.... because
the method String.valueOf(int i) implicitly calls Integer.toString(i, 10);
A search on both methods informed me all of these are equivalent:
String.valueOf(countryId)
Integer.toString(countryId)
countryId.toString() //Only if countryId is an Integer
Because they all call:
Integer.toString(countryId, 10)
The only difference is if you wish to use a different radix, ie:
Integer.toString(countryId, radix)
Personally I think countryId.toString() reads better when using an Integer. Otherwise Integer.toString(countryId) is the way to go. But that is just my personal opinion. Performance-wise you should use Integer.toString(countryId, 10).
I think that adding an empty string to an int to convert it to a String is a bad practice.

Strings are immutable - that means I should never use += and only StringBuffer?

Strings are immutable, meaning, once they have been created they cannot be changed.
So, does this mean that it would take more memory if you append things with += than if you created a StringBuffer and appended text to that?
If you use +=, you would create a new 'object' each time that has to be saved in the memory, wouldn't you?
Yes, you will create a new object each time with +=. That doesn't mean it's always the wrong thing to do, however. It depends whether you want that value as a string, or whether you're just going to use it to build the string up further.
If you actually want the result of x + y as a string, then you might as well just use string concatenation. However, if you're really going to (say) loop round and append another string, and another, etc - only needing the result as a string at the very end, then StringBuffer/StringBuilder are the way to go. Indeed, looping is really where StringBuilder pays off over string concatenation - the performance difference for 5 or even 10 direct concatenations is going to be quite small, but for thousands it becomes a lot worse - basically because you get O(N2) complexity with concatenation vs O(N) complexity with StringBuilder.
In Java 5 and above, you should basically use StringBuilder - it's unsynchronized, but that's almost always okay; it's very rare to want to share one between threads.
I have an article on all of this which you might find useful.
Rule of thumb is simple:
If you are running concatenations in a loop, don't use +=
If you are not running concatenations in a loop, using += simply does not matter. (Unless a performance critical application
In Java 5 or later, StringBuffer is thread safe, and so has some overhead that you shouldn't pay for unless you need it. StringBuilder has the same API but is not thread safe (i.e. you should only use it internal to a single thread).
Yes, if you are building up large strings, it is more efficient to use StringBuilder. It is probably not worth it to pass StringBuilder or StringBuffer around as part of your API. This is too confusing.
I agree with all the answers posted above, but it will help you a little bit to understand more about the way Java is implemented. The JVM uses StringBuffers internally to compile the String + operator (From the StringBuffer Javadoc):
String buffers are used by the
compiler to implement the binary
string concatenation operator +. For
example, the code:
x = "a" + 4 + "c"
is compiled to the equivalent of:
x = new StringBuffer().append("a").append(4).append("c")
.toString()
Likewise, x += "some new string" is equivalent to x = x + "some new string". Do you see where I'm going with this?
If you are doing a lot of String concatenations, using StringBuffer will increase your performance, but if you're only doing a couple of simple String concatenations, the Java compiler will probably optimize it for you, and you won't notice a difference in performance
Yes. String is immutable. For occasional use, += is OK. If the += operation is intensive, you should turn to StringBuilder.
But the garbage collector will end up freeing the old strings once there are no references to them
Exactly. You should use a StringBuilder though if thread-safety isn't an issue.
As a side note: There might be several String objects using the same backing char[] - for instance whenever you use substring(), no new char[] will be created which makes using it quite efficient.
Additionally, compilers may do some optimization for you. For instance if you do
static final String FOO = "foo";
static final String BAR = "bar";
String getFoobar() {
return FOO + BAR; // no string concatenation at runtime
}
I wouldn't be surprised if the compiler would use StringBuilder internally to optimize String concatenation where possible - if not already maybe in the future.
I think it relies on the GC to collect the memory with the abandoned string.
So doing += with string builder will be definitely faster if you have a lot of operation on string manipulation. But it's shouldn't a problem for most cases.
Yes you would and that is exactly why you should use StringBuffer to concatenate alot of Strings.
Also note that since Java 5 you should also prefer StringBuilder most of the time. It's just some sort of unsynchronized StringBuffer.
You're right that Strings are immutable, so if you're trying to conserve memory while doing a lot of string concatenation, you should use StringBuilder rather than +=.
However, you may not mind. Programs are written for their human readers, so you can go with clarity. If it's important that you optimize, you should profile first. Unless your program is very heavily weighted toward string activity, there will probably be other bottlenecks.
No
It will not use more memory. Yes, new objects are created, but the old ones are recycled. In the end, the amount of memory used is the same.

Categories

Resources