Skip to content

Beginner · Arrays and strings · topic 14 of 60 · 25 min

StringBuilder and formatting

Explanation

Joining Strings with + inside a loop creates a new String every time, which is slow for big loops. StringBuilder is a mutable buffer: append, insert, reverse, then toString once. printf and String.format format numbers and text (%d, %s, %.2f, %,d, %n), and text blocks (""" … """) write multi-line text cleanly.

Why StringBuilder?

Because Strings are immutable, result = result + line inside a loop creates a brand-new String each round and copies all the old characters into it. For 10 lines this does not matter; for 100,000 lines of a report it becomes very slow. StringBuilder keeps one growing buffer and changes it in place.

java
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 5; i++) {
    sb.append("Row ").append(i).append('\n');   // append returns the builder, so calls chain
}
String report = sb.toString();

StringBuilder w = new StringBuilder("Namaste");
w.insert(0, ">> ").append("!");                 // ">> Namaste!"
w.reverse();                                    // "!etsamaN >>"
System.out.println(w.length());                 // 11

Modern compilers optimise a single expression like "Total: " + total + " items", so you do not need StringBuilder there. Use it inside loops. StringBuffer is an older, synchronised (thread-safe and slower) version; prefer StringBuilder.

printf and String.format

java
String item = "Kurta";
int qty = 3;
double price = 799.5;
System.out.printf("%-10s x%2d  Rs %,10.2f%n", item, qty, qty * price);
// Kurta      x 3  Rs   2,398.50
String line = String.format("%05d", 42);   // "00042"
String pct = String.format("%.1f%%", 18.25); // "18.3%" (%% prints a percent sign)
SpecifierMeansExample → output
%dinteger%d, 42 → 42
%sstring (any object via toString)%s, "Pune" → Pune
%.2fdecimal with 2 places%.2f, 3.14159 → 3.14
%,dwith grouping separators%,d, 1234567 → 1,234,567
%5d / %-10swidth (right / left aligned)%5d, 42 → " 42"
%05dzero-padded%05d, 42 → 00042
%nplatform line break
Careful: A mismatched specifier crashes at run time: printf("%d", 3.5) throws IllegalFormatConversionException because 3.5 is not an integer. Also, %,d uses the default locale's Western grouping (1,234,567). For Indian lakh grouping use java.text.NumberFormat with Locale.of("en", "IN") (Java 19+; older code uses new Locale("en", "IN")) and check the output on your JDK, because grouping data comes from the JDK's locale data.

Text blocks (Java 15+)

java
String json = """
    {
      "orderId": "OD1023",
      "amount": 1499
    }
    """;
String sms = """
    Dear %s,
    Your OTP is %s. Do not share it with anyone.
    """.formatted("Asha", "482913");
Triple quotes start a text block; common leading spaces are removed automatically.
Think of it like this: Building a long String with + in a loop is like rewriting a whole letter by hand every time you add one sentence. StringBuilder is like a notebook where you keep writing on the same page and tear it out (toString) only at the end.
Tip: String.join(", ", list) and the Collectors.joining collector (module 8) are often the simplest way to join many values with a separator.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

StringBuilder and formatting · 1/6

StringBuilder and formatting

In this lesson you will build text efficiently and format numbers neatly.

Prefer a video by a teacher? Find free videos on “java stringbuilder vs string concatenation printf format specifiers” on YouTube ↗

In real life: Printing a GST invoice

A billing program builds the invoice text line by line with StringBuilder and formats amounts with printf-style specifiers so the columns line up neatly on a thermal printer.

java
String[] items = {"Soap", "Rice 5kg", "Oil 1L"};
double[] prices = {45, 340, 165};
StringBuilder inv = new StringBuilder("INVOICE\n");
double total = 0;
for (int i = 0; i < items.length; i++) {
    inv.append(String.format("%-10s %8.2f%n", items[i], prices[i]));
    total += prices[i];
}
inv.append(String.format("%-10s %8.2f%n", "GST 18%", total * 0.18));
inv.append(String.format("%-10s %8.2f%n", "TOTAL", total * 1.18));
System.out.print(inv);
TOTAL is 649.00 for these items (550 + 99 GST).

Practice (0/3 done)

Task 1 · Question

What does this print? StringBuilder sb = new StringBuilder("abc"); sb.append("d").reverse().insert(0, "x"); System.out.println(sb);

Task 2 · Question

What does String.format("%6.2f|%-4s|%03d", 3.14159, "ab", 7) give?

Task 3 · Practice

Write a method static String table(int n) that returns the multiplication table of n (1 to 10) as one String, each line like " 7 x 3 = 21", using StringBuilder and String.format with widths so the columns line up.

Quick quiz

Question 1

1.Why use StringBuilder in a loop?

Question 2

2.What does %n do in printf?

Question 3

3.How do you print a literal % sign with printf?

Question 4

4.Which is the older thread-safe version of StringBuilder?

Read more (free)

Before this, learn

This topic builds on these. If something here feels new, open them first.

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

Why use StringBuilder in a loop?

Answer: It avoids creating a new String object on every iteration

StringBuilder is mutable.

What does %n do in printf?

Answer: Prints the platform's line separator

%n is a portable new line.

How do you print a literal % sign with printf?

Answer: %%

%% prints one percent sign.

Which is the older thread-safe version of StringBuilder?

Answer: StringBuffer

StringBuffer methods are synchronised.

What gives you the final string from a StringBuilder sb?Related

Answer: sb.ToString()

ToString() creates the finished string.

From StringBuilder and string performance

How do you print a literal percent sign with printf?Related

Answer: %%

%% prints %.

From Input and output: printf and scanf

If x = 3.14159, what does f"{x:.2f}" give?Related

Answer: "3.14"

:.2f shows exactly two digits after the decimal point, rounding if needed.

From f-strings and string methods

How many bytes does "UPI" occupy as a string literal?Related

Answer: 4

3 letters + the terminator.

From Strings are char arrays

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 1 more topic in “Arrays and strings” before its exam: Wrapper classes and autoboxing.
  2. Module 3 exam: Arrays and strings · 12 questions · 25 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, Classes and objects. 60 topics left in the course before the final exam.

← Previous: Strings in depth