The builder only collects raw inputs; the expensive or derived computation (the total here) happens exactly once, inside the product's constructor when build() calls it. That avoids recomputing the total every time an item is added.
class Invoice {
final List<Double> items;
final double total;
private Invoice(List<Double> items) {
this.items = items;
double sum = 0;
for (double v : items) sum += v;
this.total = sum;
}
static class Builder {
private final List<Double> items = new ArrayList<>();
Builder addItem(double price) { items.add(price); return this; }
Invoice build() { return new Invoice(List.copyOf(items)); }
}
}
Invoice invoice = new Invoice.Builder().addItem(9.5).addItem(20.0).addItem(4.5).build();
System.out.println("Total computed once at build: " + invoice.total);
Total computed once at build: 34.0
Run this yourself in the Online Java Compiler, spin up a live REST API in the API Sandbox, or practise with Java interview questions.
Published 2026-09-27