☕ Java
printf()
printf() formats output using a format string containing literal text and format specifiers that are replaced with the values of subsequent arguments. It is modelled after C's printf and provides precise control over number formatting, alignment, padding, and width. In Java, printf() is available on PrintStream (System.out) and PrintWriter, and String.format() uses identical format specifiers to build formatted strings.
printf Syntax and Basic Usage
printf() takes a format string as its first argument followed by zero or more values. The format string contains ordinary characters (printed as-is) and format specifiers beginning with % that are replaced by the corresponding argument values. printf() does not add a newline — use %n (platform-independent) or \n explicitly.
Java
// ── Basic syntax: ────────────────────────────────────────────────────
// System.out.printf(formatString, arg1, arg2, ...);
// String result = String.format(formatString, arg1, arg2, ...);
// ── Simple examples: ──────────────────────────────────────────────────
System.out.printf("Hello, %s!%n", "Alice");
// Output: Hello, Alice!
System.out.printf("Age: %d%n", 30);
// Output: Age: 30
System.out.printf("Pi = %.4f%n", Math.PI);
// Output: Pi = 3.1416
System.out.printf("%s is %d years old.%n", "Bob", 25);
// Output: Bob is 25 years old.
// ── Multiple specifiers — matched left to right to arguments: ─────────
System.out.printf("%-10s %5d %.2f%n", "Alice", 95, 98.75);
System.out.printf("%-10s %5d %.2f%n", "Bob", 87, 91.50);
System.out.printf("%-10s %5d %.2f%n", "Charlie",72, 85.25);
// Output:
// Alice 95 98.75
// Bob 87 91.50
// Charlie 72 85.25
// ── printf vs println vs print: ───────────────────────────────────────
System.out.println("Hello"); // adds newline
System.out.print("Hello
"); // explicit
System.out.printf("Hello%n"); // %n = platform newline
// ── String.format — same specifiers, returns String: ──────────────────
String s = String.format("Name: %-10s Score: %3d", "Alice", 95);
System.out.println(s); // Name: Alice Score: 95
// ── formatted() — Java 15+ instance method on String: ─────────────────
String msg = "Score: %d".formatted(95);
System.out.println(msg); // Score: 95Format Specifier Reference
Every format specifier follows the pattern %[flags][width][.precision]conversion. The conversion letter determines the data type. Flags modify alignment, padding, and sign display. Width sets the minimum field width. Precision controls decimal places for floats or maximum characters for strings.
Java
// ── Format specifier structure: ──────────────────────────────────────
// % [flags] [width] [.precision] conversion
//
// % → starts every specifier
// flags → optional: -, +, 0, space, (, ,
// width → optional: minimum number of characters
// .prec → optional: decimal places (float) or max chars (string)
// conv → required: type conversion character
// ── Conversion characters: ────────────────────────────────────────────
System.out.printf("%s%n", "Hello"); // String
System.out.printf("%S%n", "Hello"); // HELLO — uppercase
System.out.printf("%c%n", 'A'); // A — char
System.out.printf("%d%n", 42); // 42 — decimal int
System.out.printf("%o%n", 42); // 52 — octal
System.out.printf("%x%n", 255); // ff — hex lowercase
System.out.printf("%X%n", 255); // FF — hex uppercase
System.out.printf("%f%n", 3.14159); // 3.141590 — float (6 decimal places default)
System.out.printf("%e%n", 123456.789); // 1.234568e+05 — scientific
System.out.printf("%E%n", 123456.789); // 1.234568E+05 — scientific uppercase
System.out.printf("%g%n", 123456.789); // 123457. — shorter of %f or %e
System.out.printf("%b%n", true); // true — boolean
System.out.printf("%B%n", true); // TRUE — boolean uppercase
System.out.printf("%n"); // platform newline
System.out.printf("100%%%n"); // 100% — literal percent
// ── Flags: ────────────────────────────────────────────────────────────
System.out.printf("'%10d'%n", 42); // ' 42' — right-align (default)
System.out.printf("'%-10d'%n", 42); // '42 ' — left-align
System.out.printf("'%010d'%n", 42); // '0000000042' — zero-pad
System.out.printf("'%+d'%n", 42); // '+42' — always show sign
System.out.printf("'%+d'%n", -42); // '-42'
System.out.printf("'% d'%n", 42); // ' 42' — space for positive
System.out.printf("'%,d'%n", 1234567); // '1,234,567' — thousands separator
System.out.printf("'%(d'%n", -42); // '(42)' — negative in parentheses
System.out.printf("'%#x'%n", 255); // '0xff' — alternate form (hex prefix)
System.out.printf("'%#o'%n", 42); // '052' — alternate form (octal prefix)Width, Precision, and Alignment
Width specifies the minimum number of characters in the output — padding is added on the left (right-align, default) or right (left-align with - flag) to reach the minimum. Precision after a decimal point specifies the number of fractional digits for floating-point numbers, or the maximum number of characters for strings. Combining width and precision creates fixed-width, aligned table columns.
Java
// ── Width — minimum field width: ─────────────────────────────────────
System.out.printf("'%5d'%n", 7); // ' 7' — padded to width 5
System.out.printf("'%5d'%n", 42); // ' 42'
System.out.printf("'%5d'%n", 999); // ' 999'
System.out.printf("'%5d'%n", 12345); // '12345' — no truncation if wider
System.out.printf("'%5d'%n", 123456); // '123456' — exceeds width, not truncated
// ── Left alignment with -: ────────────────────────────────────────────
System.out.printf("'%-5d'%n", 7); // '7 ' — left-aligned
System.out.printf("'%-5d'%n", 42); // '42 '
// ── Precision for floats: ─────────────────────────────────────────────
System.out.printf("'%f'%n", 3.14159); // '3.141590' — default 6 places
System.out.printf("'%.2f'%n", 3.14159); // '3.14' — 2 decimal places
System.out.printf("'%.0f'%n", 3.14159); // '3' — 0 decimal places
System.out.printf("'%8.2f'%n", 3.14159); // ' 3.14' — width 8, 2 places
System.out.printf("'%-8.2f'%n", 3.14159); // '3.14 ' — left-aligned
System.out.printf("'%08.2f'%n", 3.14159); // '00003.14' — zero-padded
// ── Precision for strings: ────────────────────────────────────────────
System.out.printf("'%.5s'%n", "Hello World"); // 'Hello' — truncate to 5
System.out.printf("'%10.5s'%n", "Hello World");// ' Hello' — width 10, max 5 chars
// ── Building aligned tables: ─────────────────────────────────────────
System.out.printf("%-15s %6s %8s%n", "Product", "Qty", "Price");
System.out.printf("%-15s %6s %8s%n", "─".repeat(15), "─".repeat(6), "─".repeat(8));
System.out.printf("%-15s %6d %8.2f%n", "Apple", 50, 0.99);
System.out.printf("%-15s %6d %8.2f%n", "Orange", 30, 1.49);
System.out.printf("%-15s %6d %8.2f%n", "Banana", 100, 0.59);
// Output:
// Product Qty Price
// ─────────────── ────── ────────
// Apple 50 0.99
// Orange 30 1.49
// Banana 100 0.59Common Formatting Patterns
These patterns cover the most frequent real-world printf use cases — currency, percentages, scientific notation, zero-padded IDs, dates, and multi-column reports. Each pattern combines width, precision, and flags to produce consistently formatted output.
Java
// ── Currency formatting: ─────────────────────────────────────────────
double price = 1234567.891;
System.out.printf("Price: $%,.2f%n", price); // Price: $1,234,567.89
System.out.printf("Price: $%10,.2f%n", price); // Price: $1,234,567.89
// ── Percentage: ───────────────────────────────────────────────────────
double ratio = 0.8675;
System.out.printf("Success rate: %.1f%%%n", ratio * 100); // Success rate: 86.8%
// ── Zero-padded IDs (order numbers, invoice numbers): ────────────────
int orderId = 42;
System.out.printf("Order #%08d%n", orderId); // Order #00000042
System.out.printf("INV-%05d%n", orderId); // INV-00042
// ── Scientific notation: ─────────────────────────────────────────────
double avogadro = 6.022e23;
System.out.printf("Avogadro: %e%n", avogadro); // 6.022000e+23
System.out.printf("Avogadro: %.3e%n", avogadro); // 6.022e+23
// ── Hex colour codes: ────────────────────────────────────────────────
int r = 255, g = 128, b = 0;
System.out.printf("Colour: #%02X%02X%02X%n", r, g, b); // Colour: #FF8000
// ── Negative numbers in parentheses (accounting style): ───────────────
System.out.printf("Profit: %(,.2f%n", 5000.00); // Profit: 5,000.00
System.out.printf("Loss: %(,.2f%n", -5000.00); // Loss: (5,000.00)
// ── Full invoice report: ──────────────────────────────────────────────
System.out.printf("%n%-20s %6s %10s %10s%n",
"Item", "Qty", "Unit", "Total");
System.out.printf("%-20s %6s %10s %10s%n",
"─".repeat(20), "─".repeat(6), "─".repeat(10), "─".repeat(10));
Object[][] items = {
{"Spring Boot Guide", 2, 29.99},
{"Java Complete Ref", 1, 49.99},
{"Design Patterns", 3, 34.99},
};
double grandTotal = 0;
for (Object[] item : items) {
double total = (int)item[1] * (double)item[2];
grandTotal += total;
System.out.printf("%-20s %6d %10.2f %10.2f%n",
item[0], item[1], item[2], total);
}
System.out.printf("%-20s %6s %10s %10s%n",
"─".repeat(20), "─".repeat(6), "─".repeat(10), "─".repeat(10));
System.out.printf("%-20s %17s %10.2f%n", "TOTAL", "", grandTotal);
// Output:
// Item Qty Unit Total
// ──────────────────── ────── ────────── ──────────
// Spring Boot Guide 2 29.99 59.98
// Java Complete Ref 1 49.99 49.99
// Design Patterns 3 34.99 104.97
// ──────────────────── ────── ────────── ──────────
// TOTAL 214.94Related Topics in Java Basics
Logical Operators
Logical operators combine boolean expressions into more complex conditions. Java has six of them — short-circuit and non-short-circuit variants of AND, OR, and XOR, plus logical NOT. Understanding short-circuit evaluation is essential for writing both safe and efficient conditions.
Bitwise Operators
Bitwise operators work directly on the binary representation of integers — manipulating individual bits. They're used in low-level programming, performance-critical code, flags, masks, and cryptography. Understanding them requires thinking in binary, but the patterns they enable are concise and extremely fast.
Assignment Operators
Assignment operators store values into variables. Java has one basic assignment operator and eleven compound assignment operators that combine an operation with assignment. They're concise, but have specific type behavior — especially the implicit cast in compound assignments — that every Java developer needs to understand.
Unary Operators
Unary operators take a single operand. Java has five: unary plus, unary minus, increment, decrement, and logical NOT. The increment and decrement operators have prefix and postfix forms that behave differently — a distinction that trips up developers at every level.