String Formatting in Java
printf prints formatted text straight to the screen, but often you need the formatted text as a string: to save in a file, send in an email, or show in an app. String.format and formatted build that string using the same % specifiers you met in "Format Specifiers". This lesson focuses on building strings, and on formatting numbers the way people in a particular country expect to read them.
Building a Formatted String
public class Receipt {
public static void main(String[] args) {
String header = String.format("%-10s %5s %8s", "Item", "Qty", "Amount");
String row1 = String.format("%-10s %5d %8.2f", "Rice", 3, 54.5);
String row2 = "%-10s %5d %8.2f".formatted("Ghee", 1, 249.0);
System.out.println(header);
System.out.println(row1);
System.out.println(row2);
System.out.println("Each row is " + row1.length() + " characters");
System.out.println(String.format("%2$s scored %1$d", 91, "Navika"));
}
}Item Qty Amount
Rice 3 54.50
Ghee 1 249.00
Each row is 25 characters
Navika scored 91How it works
String.format(template, values...)returns the filled-in template as aString; nothing is printed until you print it."template".formatted(values...)(Java 15) does exactly the same, written on the template.- Widths line up the columns:
%-10sis a left-aligned 10-character column,%5dand%8.2fare right-aligned. %2$sand%1$dpick arguments by position, so the template can use them in any order. That's useful when the same template is translated into another language with a different word order.
Formatting for a Country
People in different countries write numbers differently. Java's Locale describes a country's conventions, and the java.text.NumberFormat class uses it:
import java.text.NumberFormat;
import java.util.Locale;
public class Locales {
public static void main(String[] args) {
Locale india = Locale.of("en", "IN");
double amount = 1234567.5;
NumberFormat rupees = NumberFormat.getCurrencyInstance(india);
NumberFormat dollars = NumberFormat.getCurrencyInstance(Locale.US);
System.out.println(rupees.format(amount));
System.out.println(dollars.format(amount));
System.out.println(String.format(Locale.GERMANY, "%,.2f", amount));
NumberFormat compact = NumberFormat.getCompactNumberInstance(
india, NumberFormat.Style.SHORT);
System.out.println(compact.format(1_500_000));
System.out.println(NumberFormat.getPercentInstance().format(0.256));
}
}₹1,234,567.50
$1,234,567.50
1.234.567,50
15L
26%How it works
getCurrencyInstance(india)adds the rupee symbol and two decimal places. Java still groups the digits in threes here, not as 12,34,567.50.- The US format uses
$; the German format swaps the roles of.and,. getCompactNumberInstance(Java 12) writes short forms, and for India it uses lakhs: 15,00,000 becomes15L.getPercentInstancemultiplies by 100 and rounds:0.256shows as26%.
Common Mistakes
Formatting money with double and %f for real invoices. Calculate with BigDecimal, then format.
Expecting %,d to give Indian grouping. Java groups by thousands even for India; use compact format or your own helper if you need 12,34,567.
Passing the wrong type for a specifier. %d with a double throws IllegalFormatConversionException (see "Format Specifiers").
Practice
- Easy: Build a string
"Advitha | 95.50% | Rank 1"withString.formatand print it. - Harder: Format the amounts 99.5, 125000 and 2500000 in rupees, in US dollars and in compact Indian form, as a three-column table.
Key Takeaways
Was this tutorial helpful?