java.lang.StringBuilder
System.out.println(new StringBuilder("I like")
.append(cake)
.append(" and I eat ")
.append(cakeNumber)
.append(" blah blah prolonging this string because ")
.append(whyNot)
.append(" and so on ")
.append(number)
.append(".")
.toString());
java.text.MessageFormat
System.out.println(MessageFormat.format("I like {0} and I eat {1} blah blah prolonging this string because {2} and so on {3}.",
cake, cakeNumber, whyNot, number));
I kind of like it with a static import, like this:
import static java.text.MessageFormat.format;
System.out.println(format("I like {0} and I eat {1} blah blah prolonging this string because {2} and so on {3}.",
cake, cakeNumber, whyNot, number));
java.util.Formatter (also known as String.format)
System.out.printf("I like %s and I eat %d blah blah prolonging this string because %s and so on %f.%n",
cake, cakeNumber, whyNot, number);
You have lots of syntactic choice at your disposal here (Just to list some, there is probably more):
System.out.format(...)
System.out.printf(...)
System.out.print(String.format(...)) // you will need to include the line break in the format
System.out.println(String.format(...)) // line break will be caused by println()
import static java.lang.String.format;
System.out.print(format(...))
System.out.println(format(...))
System.out.println(new Formatter().format(...))
%n represents the system's specific line break character. It is required because printf does not insert a line break after the operation automatically.
Multiline string concatenation
System.out.println("I like " + cake + " and I eat " +
cakeNumber + " blah blah prolonging this string because" +
whyNot + " and so on " + number + ".");
Answer from randers on Stack OverflowJava - String Formatting
Should I use Java's String.format() if performance is important? - Stack Overflow
[Java] How can I convert a string of long text into IPA?
String.format() is 3x faster in Java 17
java.lang.StringBuilder
System.out.println(new StringBuilder("I like")
.append(cake)
.append(" and I eat ")
.append(cakeNumber)
.append(" blah blah prolonging this string because ")
.append(whyNot)
.append(" and so on ")
.append(number)
.append(".")
.toString());
java.text.MessageFormat
System.out.println(MessageFormat.format("I like {0} and I eat {1} blah blah prolonging this string because {2} and so on {3}.",
cake, cakeNumber, whyNot, number));
I kind of like it with a static import, like this:
import static java.text.MessageFormat.format;
System.out.println(format("I like {0} and I eat {1} blah blah prolonging this string because {2} and so on {3}.",
cake, cakeNumber, whyNot, number));
java.util.Formatter (also known as String.format)
System.out.printf("I like %s and I eat %d blah blah prolonging this string because %s and so on %f.%n",
cake, cakeNumber, whyNot, number);
You have lots of syntactic choice at your disposal here (Just to list some, there is probably more):
System.out.format(...)
System.out.printf(...)
System.out.print(String.format(...)) // you will need to include the line break in the format
System.out.println(String.format(...)) // line break will be caused by println()
import static java.lang.String.format;
System.out.print(format(...))
System.out.println(format(...))
System.out.println(new Formatter().format(...))
%n represents the system's specific line break character. It is required because printf does not insert a line break after the operation automatically.
Multiline string concatenation
System.out.println("I like " + cake + " and I eat " +
cakeNumber + " blah blah prolonging this string because" +
whyNot + " and so on " + number + ".");
Try printf
For example, you could write
System.out.printf("I like %s and I eat %d blah blah prolonging this string because %s and so on %0.f.\n", cake, cakenumber, whyNot, number);
Also note that many IDEs (like Eclipse) will allow you to easily span strings across many lines. But the advantage of printf is that you separate the string from the variables, and also allows for better control over the display of numbers. For example, notice the %.0f. In general you can specify how much space the value should take up including padding and how many decimal places to use.
/**
* Call String.format with three integer arguments and
* display them in reverse order.
* @param num1 50
* @param num2 60
* @param num3 70
* @param num4 80
*
* Output:
* Fourth: 50
* Third: 60
* Second: 70
* First: 80
*/
public static void reverseNums(add a parameter list here){ //#1
String reverse = String.format(add a format string here); //#2 System.out.println(reverse);
}
We are supposed to reverse these numbers, however my question is how is it possible to pass the numbers as arguments into the String.format() method, can't I only pass in Strings? A nudge in the right direction would be a huge help. Thanks
I took hhafez's code and added a memory test:
private static void test() {
Runtime runtime = Runtime.getRuntime();
long memory;
...
memory = runtime.freeMemory();
// for loop code
memory = memory-runtime.freeMemory();
I run this separately for each approach, the '+' operator, String.format and StringBuilder (calling toString()), so the memory used will not be affected by other approaches. I added more concatenations, making the string as "Blah" + i + "Blah"+ i +"Blah" + i + "Blah".
The result are as follows (average of 5 runs each):
| Approach | Time(ms) | Memory allocated (long) |
|---|---|---|
+ operator |
747 | 320,504 |
String.format |
16484 | 373,312 |
StringBuilder |
769 | 57,344 |
We can see that String + and StringBuilder are practically identical time-wise, but StringBuilder is much more efficient in memory use.
This is very important when we have many log calls (or any other statements involving strings) in a time interval short enough so the Garbage Collector won't get to clean the many string instances resulting of the + operator.
And a note, BTW, don't forget to check the logging level before constructing the message.
Conclusions:
- I'll keep on using
StringBuilder. - I have too much time or too little life.
I wrote a small class to test which has the better performance of the two and + comes ahead of format. by a factor of 5 to 6. Try it your self
import java.io.*;
import java.util.Date;
public class StringTest{
public static void main( String[] args ){
int i = 0;
long prev_time = System.currentTimeMillis();
long time;
for( i = 0; i< 100000; i++){
String s = "Blah" + i + "Blah";
}
time = System.currentTimeMillis() - prev_time;
System.out.println("Time after for loop " + time);
prev_time = System.currentTimeMillis();
for( i = 0; i<100000; i++){
String s = String.format("Blah %d Blah", i);
}
time = System.currentTimeMillis() - prev_time;
System.out.println("Time after for loop " + time);
}
}
Running the above for different N shows that both behave linearly, but String.format is 5-30 times slower.
The reason is that in the current implementation String.format first parses the input with regular expressions and then fills in the parameters. Concatenation with plus, on the other hand, gets optimized by javac (not by the JIT) and uses StringBuilder.append directly.
