From the docs:
The format specifiers for general, character, and numeric types have the following syntax:
%[argument_index$][flags][width][.precision]conversionThe optional argument_index is a decimal integer indicating the position of the argument in the argument list. The first argument is referenced by
"1$", the second by"2$", etc.
String.format("%1
s %1
s %1
s", hello);
Answer from Ignacio Vazquez-Abrams on Stack OverflowFrom the docs:
The format specifiers for general, character, and numeric types have the following syntax:
%[argument_index$][flags][width][.precision]conversionThe optional argument_index is a decimal integer indicating the position of the argument in the argument list. The first argument is referenced by
"1$", the second by"2$", etc.
String.format("%1
s %1
s %1
s", hello);
Another option is to use relative indexing: The format specifier references the same argument as the last format specifier.
For example:
String.format("%s %<s %<s %<s", "hello")
results in hello hello hello hello.
java - Can Stringformatter reuse arguments? - Stack Overflow
java - how to format a string with same value for all placeholders - Stack Overflow
JAVA, interpolate n times the same variable with String.format - Stack Overflow
How to format multiple string parameters in Java - Stack Overflow
Yes, you can use the $ specifier for this. The number preceding the $ indicates the argument number, starting from 1:
String.format("%1
s %1$s", "test")
Just as a complement to Keppils answer: When you've started numbering one of your arguments, you have to number them all, or else the result will not be as expected.
String.format("Hello %1$s! What a %2
s!", "world", "wonderful");
// "Hello world! What a wonderful world!"
would work. While
String.format("Hello %1$s! What a %s %1$s!", "world", "wonderful");
// "Hello world! What a world world!"
would not work. (But does not throw any errors, so this might go unnoticed.)
You can simply reference a specific argument:
String.format("Hello %1$s, your name is %1$s", "Mr.P")
% = Start of format string
1$ = First argument
s = Type String
EDIT: It appears that String.format is smarter than I thought. Do the positional syntax given by @Michael
Use MessageFormat.
import java.text.MessageFormat;
...
String str = "Hello {0}, your name is {0}, {0}'s born in 1990.";
String str2 = MessageFormat.format(str, "Mr. P");
System.out.println(str2);
Hello Mr. P, your name is Mr. P, Mr. Ps born in 1990.
This has the advantage of allowing you to create multiple placeholders and move them around in your pattern.
Docs: MessageFormat
You could do that (while harcoded in terms of occurrence):
String value = "hi";
String interpolated = String.format(" %s %s %s %s ", IntStream.range(0, 4)
.mapToObj(i -> value)
.toArray());
You could variabilize it in this way :
public String repeat(String string, int nbRepeat){
return String.format(" " + IntStream.range(0, nbRepeat)
.mapToObj(i -> "%s")
.collect(Collectors.joining(" ")),
IntStream.range(0, nbRepeat)
.mapToObj(
i -> string)
.toArray());
}
And use it :
repeat("hi", 4);
repeat("ho", 6);
..Isn't there cleaner way?
Well it depends on how you want to use it; if you want to avoid streams, you can use any of the below:
package sample;
import java.util.Arrays;
import java.util.Formatter;
public class JoinString {
public static void main(String[] args) {
String[] v = {"hi","hi","hi","hi"};
System.out.println(String.join(" ", v));
System.out.println(Arrays.asList(v));
Formatter formatter = new Formatter();
System.out.println( formatter.format("%1$1s %1$1s %1$1s", "hi"));
formatter.close();
System.out.format("%1$1s %1$1s %1$1s %n", "hi");
}
}
If you want to put the result in a String you can use :
String result = String.format("%-30s %-30s %-30s", divName, heading1, heading2);
Then you can print it or use it in another places
To get formatting on each of them you need to pass them separately to printf rather than combining them into one string with +.
System.out.printf("%-30s %-30s %-30s", divName, heading1, heading2);
I am currently learning the string formatting topic and I have searched many places only to get *args and *kwargs (completely unrelated to my question) as my answer. Coming back to my question....
Let's say I have a code to convert decimal numbers to binary, octal and hexadecimal. I wrote the code something like this
num = int(input("Enter an integer: "))
print("Binary of {0} is {1:b}".format(num, num))
print("Hexadecimal of {0} is {1:x}".format(num, num))
print("Octal of {0} is {1:o}".format(num, num))Here, in the string format method, I am passing 'num' twice to reflect in the printed message. Is there anyway to pass 'num' once to all the placeholders {} in the string?
One more example:
can you can a can as a canner can can a can
For a statement like this, you can code something like below which has repeating "can"s. Instead I want to pass a single string variable for all the placeholders
print("{0} you {1} a {2} as a canner {3} {4} a {5}".format("can", "can", "can", "can", "can", "can"))Note: Please do suggest a solution to the above, if one such exists. If it doesn't, you can say no. Please please please avoid statements like "You can directly print the string as such instead of going through this ordeal!"
Yes, you can use %1$d everytime. The 1$ references the second argument, you could obviously do it with other arguments, too.
Demo: http://codepad.org/xVmdJkpN
Note that the position specifier is a POSIX extension - so it might not work with every single compiler. If you need it to work e.g. with the Visual C++ compiler, consider using the ugly way of repeating the argument or do not use a printf-style function at all. Another option would be using a POSIX-compatible sprintf implementation or using multiple calls to append one number everytime in a loop (in case the format string is built dynamically which would prevent you from specifying the correct number of arguments).
On a side-note, sprintf should be avoided. Use snprintf(buf2, sizeof(buf2), ....) instead. Of course this requires buf2 to have a static size known at compile-time - but if you allocate it manually you can simply use the variable containing the length instead of sizeof(buf2).
There is no standard (i.e. portable) way of doing this.