# string-format Companion code for the ankurm.com post *"String.format, formatted() and printf in Java: The Complete Cheat Sheet."* Module in `java-core-examples`, the Java-core series. ## Versions this was built and tested against | Component | Version | Notes | |---|---|---| | JDK | 25.0.5+8 (Temurin, LTS) | `String.format` is Java 5; `String.formatted()` arrived in Java 15; `Formatter` parsing was rewritten without regex in Java 17. | | JUnit Jupiter | 5.11.0 | | | Maven | 3.9.11 | | ## Quickstart ```bash export JAVA_HOME=/path/to/jdk-25 mvn compile scripts/run.sh IndianGroupingDemo # one demo scripts/run-all.sh # regenerate every file in output/ ``` ## What's in here | File | What it shows | |---|---| | `BasicsDemo.java` | Every part of `%[index$][flags][width][.precision]conversion`, changed one at a time. | | `ReportTableDemo.java` | Left/right alignment, zero padding, truncation with `%.Ns`, a fixed-width invoice, `printf`. | | `RoundingDemo.java` | `%f` rounds HALF_UP on the decimal string, so it disagrees with C `printf` and with `BigDecimal(double)`. | | `IndianNumberFormat.java` + `IndianGroupingDemo.java` | **The main exhibit.** Every built-in route to lakh/crore grouping tried and shown to fail, then a 60-line formatter that works. | | `LocaleDemo.java` | The same `%,.2f` under six locales; the default-locale trap; what is *not* localized. | | `FormatErrorsDemo.java` | Twelve format strings that compile and then throw (or, for `"50% off"`, throw something surprising), with the real exception text. | | `FormattedAndPrintfDemo.java` | `format` / `formatted` / `printf` / `Formatter` are one engine; text-block pairing; varargs and arrays. | | `DateTimeDemo.java` | `%tF`, `%tT`, `%tA` on `java.time` values, localized names, and why `%tH` on a `LocalDate` throws. | | `ConcatBenchmarkDemo.java` | Indicative cost of `+`, `StringBuilder`, `formatted`, `format`. A warmed plain loop, not JMH. | | `StringFormatTest.java` | Pins every claim above as an assertion, 11/11 passing. | | `scripts/printf_compare.c` | The same values through C `printf`, for the rounding comparison. | | `output/01-11` | Captured runs of everything above. Timing in `08` drifts between runs. | ## Notes worth knowing before reading the post - **`%,d` cannot produce lakh/crore grouping in any locale.** `en_IN` and `hi_IN` both print `123,456,789` (`output/04`). The `,` flag takes one grouping size from `DecimalFormat.getGroupingSize()`, and a `DecimalFormat` built from `#,##,##0` reports a grouping size of 3. - **`"Discount 50% off"` throws `MissingFormatArgumentException`**, not an unknown-conversion error: `% o` parses as the space flag plus the octal conversion (`output/06`). - **`%f` on a `double` rounds the decimal string, `%f` on a `BigDecimal` rounds the exact value**, so `2.675` formats as `2.68` one way and `2.67` the other (`output/03`). ## License MIT - see the [repo-wide LICENSE](../LICENSE).