Java Formatting Output

In the last lesson you learned about Java reading numeric input. Now you can pull numbers in. But getting them back out neatly is a different problem. Plain println just dumps whatever you give it:

  • A price prints as 19.989999999.
  • Columns of names and prices wander all over the place.
  • Messy output makes a program feel broken even when the logic is perfect.

This lesson puts you in charge of how text looks: round numbers, pad them, line up columns, add currency signs.

πŸ–¨οΈ printf and String.format

Two close cousins do the formatting:

  • System.out.printf prints formatted text straight to the screen.
  • String.format builds the same text and hands it back as a String.

Here is the simplest printf. It drops a number into a sentence.

public class FirstFormat {
public static void main(String[] args) {
int score = 42;
System.out.printf("Your score is %d%n", score);
}
}

Reading that line:

  • The text in quotes is the format string.
  • %d is a placeholder meaning β€œdrop a whole number here”.
  • score after the comma fills that placeholder.
  • %n means β€œstart a new line”.

Output

Your score is 42

Now the same idea with String.format. Nothing prints by itself; you catch the result in a variable.

public class StringFormatDemo {
public static void main(String[] args) {
int score = 42;
String message = String.format("Your score is %d", score);
System.out.println(message);
}
}

Which one to use:

  • printf when you just want to print.
  • String.format when you want to keep the text, to save it or build a longer string.

Output

Your score is 42

πŸ”€ The basic format specifiers

A placeholder like %d is called a format specifier. Each one matches a kind of value, and the wrong one crashes the program. This program shows one of each in action.

public class Specifiers {
public static void main(String[] args) {
int age = 30;
double price = 4.5;
String name = "Alex";
char grade = 'A';
boolean active = true;
System.out.printf("Int: %d%n", age);
System.out.printf("Double: %f%n", price);
System.out.printf("String: %s%n", name);
System.out.printf("Char: %c%n", grade);
System.out.printf("Boolean: %b%n", active);
}
}

Each line picks the specifier that fits its value: %d takes the whole number, %f the decimal, %s the text, %c the single character, %b the true or false.

Output

Int: 30
Double: 4.500000
String: Alex
Char: A
Boolean: true

Notice %f printed 4.500000 with six decimal places. That is the default, and rarely what you want; we fix it next. Quick reference for the common specifiers:

%d whole number (int, long)
%f decimal number (float, double)
%s text (String, or anything)
%c single character (char)
%b true or false (boolean)
%n a new line (no value needed)

One handy note: %s accepts almost anything and turns it into text. When unsure, %s is the safe choice for display.

🎯 Controlling decimal places

Six digits after the decimal look noisy. To pick how many you want, put a dot and a number between the % and the f:

  • %.2f means β€œtwo decimal places”.
  • Java rounds the value for you.

This program prints the same number with different precision.

public class Decimals {
public static void main(String[] args) {
double value = 3.14159265;
System.out.printf("Default: %f%n", value);
System.out.printf("Two places: %.2f%n", value);
System.out.printf("One place: %.1f%n", value);
System.out.printf("Whole: %.0f%n", value);
}
}

The number after the dot sets how many digits show: %.2f keeps two, %.1f keeps one, %.0f drops them all. Rounding is automatic, so 3.14159 becomes 3.14.

Output

Default: 3.141593
Two places: 3.14
One place: 3.1
Whole: 3

This is the format you reach for most. Prices, averages, measurements: almost anything with a decimal looks better with %.2f.

πŸ“ Width and alignment

To make columns line up, give each value a fixed width with a width number right after the %:

  • %5d means β€œmake this at least five characters wide”.
  • If it is shorter, Java adds spaces on the left.
  • That right-aligns the value.

This program prints numbers of different lengths, each in a five-wide slot.

public class Width {
public static void main(String[] args) {
System.out.printf("[%5d]%n", 7);
System.out.printf("[%5d]%n", 42);
System.out.printf("[%5d]%n", 1234);
}
}

The brackets just show the padding. Each number sits in a five-wide space, pushed right, with spaces filling the gap on the left.

Output

[ 7]
[ 42]
[ 1234]

Default padding goes on the left, lining numbers up on their right edge. Text usually wants the opposite:

  • Put a minus sign before the width, like %-10s.
  • That left-aligns the value and pads on the right.

This program shows right-aligned versus left-aligned text.

public class Alignment {
public static void main(String[] args) {
System.out.printf("[%10s]%n", "Alex");
System.out.printf("[%-10s]%n", "Alex");
}
}

The first line pads left, so Alex hugs the right edge. The second has the minus sign, so it pads right and Alex hugs the left edge.

Output

[ Alex]
[Alex ]

0️⃣ Zero-padding and thousands separators

Two more tricks make numbers look professional. The first is zero-padding:

  • Put a 0 before the width, like %05d.
  • Java fills the empty space with zeros instead of spaces.
  • Great for invoice numbers, dates, and clocks.

This program pads a number to five digits with leading zeros.

public class ZeroPad {
public static void main(String[] args) {
System.out.printf("Order #%05d%n", 42);
System.out.printf("Time: %02d:%02d%n", 9, 5);
}
}

The %05d gives 42 three leading zeros to reach five digits. The clock uses %02d twice, so a single-digit 5 becomes 05, just like a digital clock.

Output

Order #00042
Time: 09:05

The second trick is the thousands separator. Big numbers are hard to read without commas:

  • Put a comma flag after the %, like %,d.
  • Java groups the digits for you.

This program prints a large number with and without grouping.

public class Grouping {
public static void main(String[] args) {
long population = 1234567;
System.out.printf("Plain: %d%n", population);
System.out.printf("Grouped: %,d%n", population);
System.out.printf("Money: %,.2f%n", 1234567.5);
}
}

The plain version is a wall of digits. The %,d version adds commas every three digits. Flags also combine, so %,.2f adds commas and two decimal places at once.

Output

Plain: 1234567
Grouped: 1,234,567
Money: 1,234,567.50

πŸ’° Currency and percentages

For currency, combine a currency symbol with %,.2f to get grouped digits and exactly two decimals. This program formats a price.

public class Money {
public static void main(String[] args) {
double total = 2499.5;
System.out.printf("Total: $%,.2f%n", total);
}
}

The dollar sign is plain text. The %,.2f does the work, adding comma grouping and rounding to two decimals so it reads like a real price tag.

Output

Total: $2,499.50

Percentages have one catch. The % character is special inside a format string, so to print a real percent sign you write %%. This program prints a percentage value.

public class Percent {
public static void main(String[] args) {
double passRate = 87.5;
System.out.printf("Pass rate: %.1f%%%n", passRate);
}
}

The tail packs three jobs together:

  • %.1f formats the number to one decimal.
  • %% prints a single % sign.
  • %n ends the line.

Output

Pass rate: 87.5%

πŸ“Š Building an aligned table

Now put it all together for a tidy table. The trick is a fixed width per column:

  • Left-align text so words start at the same place.
  • Right-align numbers so they end at the same place.

This program prints a price list with three lined-up columns.

public class PriceTable {
public static void main(String[] args) {
System.out.printf("%-10s %5s %10s%n", "Item", "Qty", "Price");
System.out.printf("%-10s %5d %10.2f%n", "Apples", 3, 4.5);
System.out.printf("%-10s %5d %10.2f%n", "Bread", 12, 25.0);
System.out.printf("%-10s %5d %10.2f%n", "Milk", 1, 199.99);
}
}

Every row uses the same widths:

  • Item name: left-aligned ten-wide slot with %-10s.
  • Quantity: right-aligned five-wide slot.
  • Price: right-aligned ten-wide slot with two decimals.

Shared widths are why the columns line up perfectly.

Output

Item Qty Price
Apples 3 4.50
Bread 12 25.00
Milk 1 199.99

That is the whole secret to neat tables: pick a width per column, then reuse the same format string for every row.

Reuse one format string

When you print many rows, store the format string in a variable once and pass it to every printf call. If you ever need to adjust a column width, you change it in one place and every row updates together.

⚠️ Common Mistakes

A few slip-ups trip up almost everyone. Each comes with the fix beside it.

First, the wrong specifier for the type. %d expects a whole number; hand it a double and the program crashes.

// ❌ Wrong: %d with a double crashes at runtime
double price = 9.99;
System.out.printf("Price: %d%n", price);
// βœ… Right: use %f (with decimals) for a double
double price = 9.99;
System.out.printf("Price: %.2f%n", price);

The wrong version throws IllegalFormatConversionException, meaning the specifier did not match the value’s type. Match %d to whole numbers and %f to decimals.

Second, forgetting %n. Without it, everything runs together on one line.

// ❌ Wrong: no %n, so the lines stick together
System.out.printf("First");
System.out.printf("Second");
// prints: FirstSecond
// βœ… Right: end each line with %n
System.out.printf("First%n");
System.out.printf("Second%n");

Unlike println, printf never adds a line break. You add %n yourself wherever you want a new line.

Third, putting %f on an int. The %f specifier wants a decimal type, so an int makes it crash.

// ❌ Wrong: %f with an int crashes
int count = 5;
System.out.printf("Count: %f%n", count);
// βœ… Right: use %d for an int, or convert if you really want decimals
int count = 5;
System.out.printf("Count: %d%n", count);
System.out.printf("Count: %.2f%n", (double) count);

To show an int with decimals, convert it to a double first, as the last line does.

βœ… Best Practices

A few habits keep formatted output clean and bug-free.

  • Match the specifier to the type. %d for whole numbers, %f for decimals, %s for text. A mismatch is a runtime crash, not a quiet warning.
  • Always end lines with %n. It is the cross-platform newline, and printf never adds one on its own.
  • Use %.2f for money and measurements. Two decimals is the standard, and it rounds cleanly instead of showing six noisy digits.
  • Reach for %,d and %,.2f on big numbers. The comma grouping makes large amounts readable at a glance.
  • Share one format string across table rows. Define the widths once and reuse them, so columns always line up and changes stay easy.
  • Pick String.format when you need the text later. Use printf to print right away, and String.format to build a string you will store or pass on.

🧩 What You’ve Learned

Nice work. Your output can look polished now instead of raw.

  • βœ… System.out.printf prints formatted text, and String.format builds the same text as a String.
  • βœ… The core specifiers are %d for whole numbers, %f for decimals, %s for text, %c for a char, %b for a boolean, and %n for a new line.
  • βœ… %.2f rounds to a chosen number of decimal places.
  • βœ… A width like %5d right-aligns, and a minus like %-10s left-aligns, which is how you line up columns.
  • βœ… %05d zero-pads, and %,d adds thousands separators.
  • βœ… Combine flags for money with %,.2f, and print a literal percent sign with %%.

Check Your Knowledge

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    What does %.2f do to the value 3.14159?

    Why: %.2f keeps two digits after the decimal point and rounds, so 3.14159 prints as 3.14.

  2. 2

    How do you make a number right-aligned in a five-character-wide space?

    Why: %5d sets a minimum width of five and pads with spaces on the left, which right-aligns the number.

  3. 3

    What happens if you use %d with a double value?

    Why: %d expects a whole number. Passing a double does not convert it, it throws IllegalFormatConversionException.

  4. 4

    How do you print a literal percent sign in a format string?

    Why: The % character is special, so you write %% to print one real percent sign.

πŸš€ What’s Next?

You can read input and print clean, formatted output. The next piece is getting data into your program before it even starts running, straight from the command line. That opens the door to flexible tools and scripts.

Java Command-Line Arguments

Share & Connect