Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Java StringBuilder: bounded text assembly

Last updated: 28 Sept 20263 min read
tutorial
IntermediateBy AITrove Editorial

StringBuilder stores a mutable sequence of UTF-16 code units so a caller can assemble text without replacing the complete result after every append.

Java 8+. Use a JDK that supports this release.

Build a report with one owner

A batch export needs one line per accepted shipment. Give the builder to that method alone. Sharing it among workers requires a coordination rule, and changing the class to StringBuffer does not make a multi-step report transaction atomic.

Capacity is reserved storage; length is the amount of text currently present. Reserving a measured starting capacity can reduce growth, but reserving a megabyte for every tiny report simply transfers the cost to idle memory. This program uses a small hint and rejects reports whose final line would exceed the contract.

Text is not escaped merely because it came through append. If the destination is HTML, JSON, SQL, or a spreadsheet, its encoding rules remain separate. The sample accepts only integer shipment IDs and emits plain text, so it does not claim to solve those formats.

Check before appending

The line is built independently so the size check can reject it before modifying the accumulated report. That temporary allocation trades a small per-line cost for a simple failure boundary. A streaming writer is preferable when the report can exceed available memory.

length measures UTF-16 units, not displayed glyphs or UTF-8 bytes. A byte-based transport limit needs an encoded-byte budget. Read the String lesson before treating text indexes as user-visible character positions.

Working program

Java
public class ShipmentReport {
    static String render(int[] shipmentIds, int maxUnits) {
        StringBuilder report = new StringBuilder(Math.min(maxUnits, 64));
        for (int shipmentId : shipmentIds) {
            String line = "shipment=" + shipmentId + "\n";
            if (line.length() > maxUnits - report.length()) {
                throw new IllegalArgumentException("Report exceeds text budget");
            }
            report.append(line);
        }
        return report.toString();
    }
    public static void main(String[] args) {
        System.out.print(render(new int[]{418, 509}, 64));
    }
}

Output

Output
shipment=418
shipment=509

Cost and design choices

For L output units, growing and copying the accumulated buffer takes amortised O(L) work under ordinary geometric growth. Converting to String also materialises a result; the builder and result can coexist during the call. Budget O(L) live storage rather than assuming append removes all allocation.

An insert at the start shifts existing text. Repeating that edit across a growing report can be quadratic. Append in output order, or collect fragments and join once.

Common Mistakes

  • Validate negative limits before allocating.
  • Do not confuse capacity with length.
  • Do not reuse a builder as shared mutable service state.

Connect the contracts

Compare the boundary explained in Streaming file output with the assumptions made by this program.

java
stringbuilder
Storage details