Files

53 lines
2.9 KiB
Markdown

# 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).