Java Academy · Oppitunti

NumberFormat ja printf

Muotoile luvut näyttöä varten NumberFormatin, DecimalFormatin ja printf-mallien avulla.

Oppitunti 4/413 vaihetta

NumberFormat ja printf on ilmainen Java Academy-oppitunti CoddyKitissä. Tämä on oppitunti 4/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Java Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Java Academy-kurssilla on yhteensä 4 oppituntia.

NumberFormat ja printf

Java tarjoaa monipuoliset lukujen muotoilurajapinnat: NumberFormat maa-asetusten mukaiseen valuutan ja prosenttien muotoiluun, DecimalFormat mukautettuihin malleihin sekä printf/String.format C-tyyliseen muotoiluun.

String.format-perusteet

String.format() käyttää muotoilumääritteitä merkkijonojen muodostamiseen. Yleisiä määritteitä ovat: %d (kokonaisluku), %f (liukuluku), %s (merkkijono) ja %n (rivinvaihto).

String name = "Alice";
int score = 95;
double avg = 87.567;

String msg = String.format(
    "Player: %s | Score: %d | Average: %.2f", name, score, avg);
System.out.println(msg);
// Player: Alice | Score: 95 | Average: 87.57

// printf is equivalent — formats directly to output
System.out.printf("%-10s %5d %8.2f%n", name, score, avg);
// Alice          95    87.57

Leveys, täyttö ja tasaus

Muotoilumääritteet tukevat leveyttä ja tasauslippuja: %10d (tasaus oikealle 10 merkin levyisessä kentässä), %-10d (tasaus vasemmalle), %010d (nollatäyttö).

// Table layout with padding
System.out.printf("%-20s %10s %10s%n", "Product", "Qty", "Price");
System.out.printf("%-20s %10d %10.2f%n", "Java Book", 3, 49.99);
System.out.printf("%-20s %10d %10.2f%n", "USB Hub", 1, 24.95);
System.out.printf("%-20s %10d %10.2f%n", "Mechanical Keyboard", 2, 129.00);

// Zero-padding for order IDs
int orderId = 42;
System.out.printf("Order: ORD-%08d%n", orderId); // Order: ORD-00000042

NumberFormat valuutalle

NumberFormat.getCurrencyInstance(Locale) muotoilee luvut valuuttamerkkijonoiksi ja käyttää annetun maa-asetuksen mukaista valuuttatunnusta, erotinmerkkejä ja desimaalien määrää.

import java.text.*;
import java.util.*;

NumberFormat usd = NumberFormat.getCurrencyInstance(Locale.US);
NumberFormat eur = NumberFormat.getCurrencyInstance(Locale.GERMANY);
NumberFormat gbp = NumberFormat.getCurrencyInstance(Locale.UK);

double amount = 1234567.89;
System.out.println(usd.format(amount)); // $1,234,567.89
System.out.println(eur.format(amount)); // 1.234.567,89 EUR
System.out.println(gbp.format(amount)); // GBP1,234,567.89

NumberFormat prosenteille

NumberFormat.getPercentInstance() muotoilee desimaaliarvon prosenttimerkkijonoksi. Antakaa sille arvo väliltä 0–1.

import java.text.*;
import java.util.*;

NumberFormat pct = NumberFormat.getPercentInstance(Locale.US);
pct.setMaximumFractionDigits(1);

System.out.println(pct.format(0.75));     // 75%
System.out.println(pct.format(0.1234));   // 12.3%
System.out.println(pct.format(1.0));      // 100%

// Conversion rate in e-commerce
double convRate = 3_456.0 / 42_000.0;
System.out.println("Conversion: " + pct.format(convRate)); // 8.2%

DecimalFormat mukautetuilla malleilla

DecimalFormat käyttää mallimerkkijonoa, jossa # tarkoittaa valinnaista numeroa ja 0 pakollista numeroa.

import java.text.*;

DecimalFormat df1 = new DecimalFormat("#,###.00");
System.out.println(df1.format(1234567.5));  // 1,234,567.50

DecimalFormat df2 = new DecimalFormat("000.0");
System.out.println(df2.format(7.5));  // 007.5

DecimalFormat df3 = new DecimalFormat("0.00E0");
System.out.println(df3.format(0.000123)); // 1.23E-4

// Scientific notation for large values
DecimalFormat sci = new DecimalFormat("0.000E0");
System.out.println(sci.format(123456789)); // 1.235E8

Lukujen jäsentäminen merkkijonoista

NumberFormat voi myös jäsentää maa-asetusten mukaisesti muotoiltuja merkkijonoja takaisin luvuiksi. Tämä on olennaista käsiteltäessä käyttäjän syötteitä eri maa-asetuksilla.

import java.text.*;
import java.util.*;

NumberFormat nf = NumberFormat.getInstance(Locale.GERMANY);
try {
    // German uses comma as decimal separator
    Number parsed = nf.parse("1.234,56");
    System.out.println(parsed.doubleValue()); // 1234.56

    // Parse US currency string
    NumberFormat usd = NumberFormat.getCurrencyInstance(Locale.US);
    Number amount = usd.parse("$1,234.56");
    System.out.println(amount.doubleValue()); // 1234.56
} catch (ParseException e) {
    System.out.println("Parse error: " + e.getMessage());
}

Muotoillut merkkijonot (Java 15+)

Java 15+ lisää String.formatted()-menetelmän, joka on vaihtoehto ilmentymämenetelmänä käytettävälle String.format()-menetelmälle. Se on hyödyllinen menetelmäketjuissa ja stream-käsittelyputkissa.

record Product(String name, double price, int stock) {}

var products = List.of(
    new Product("Laptop", 999.0, 5),
    new Product("Mouse",  29.99, 42),
    new Product("Monitor", 349.0, 8)
);

products.stream()
    .map(p -> "%-15s $%8.2f  [stock: %d]"
        .formatted(p.name(), p.price(), p.stock()))
    .forEach(System.out::println);
// Laptop          $  999.00  [stock: 5]
// Mouse           $   29.99  [stock: 42]
// Monitor         $  349.00  [stock: 8]

Lukujen ryhmittely ja maa-asetukset

Lukujen ryhmittely (tuhaterotin) vaihtelee maa-asetuksen mukaan. Käyttäkää käyttäjälle näytettävään tulostukseen aina NumberFormat-luokkaa sen sijaan, että määrittelisitte pilkut kiinteästi.

import java.text.*;
import java.util.*;

long users = 1_234_567;

for (Locale locale : new Locale[]{Locale.US, Locale.FRANCE, Locale.GERMANY}) {
    NumberFormat nf = NumberFormat.getIntegerInstance(locale);
    System.out.printf("%-10s: %s%n", locale, nf.format(users));
}
// en_US     : 1,234,567
// fr_FR     : 1 234 567
// de_DE     : 1.234.567

Laskun muodostamisen esimerkki

Kootaan opitut asiat: muodostetaan muotoiltu laskutuloste, jossa valuutta, prosentit ja taulukon tasaus esitetään oikein.

import java.text.*;
import java.util.*;

NumberFormat curr = NumberFormat.getCurrencyInstance(Locale.US);
NumberFormat pct  = NumberFormat.getPercentInstance();
pct.setMaximumFractionDigits(0);

double subtotal = 1259.97;
double discount = 0.10;
double discountAmt = subtotal * discount;
double taxRate = 0.08;
double taxAmt = (subtotal - discountAmt) * taxRate;
double total = subtotal - discountAmt + taxAmt;

System.out.println("=== INVOICE ===");
System.out.printf("%-20s %15s%n", "Subtotal",       curr.format(subtotal));
System.out.printf("%-20s %15s%n", "Discount (" + pct.format(discount) + ")",
    "-" + curr.format(discountAmt));
System.out.printf("%-20s %15s%n", "Tax (" + pct.format(taxRate) + ")",
    curr.format(taxAmt));
System.out.printf("%-20s %15s%n", "TOTAL", curr.format(total));

Yleiset sudenkuopat

Varokaa näitä yleisiä muotoiluvirheitä:

  • String.format-menetelmän käyttäminen väärän tyyppimääritteen kanssa (esimerkiksi %d tyypille double) aiheuttaa IllegalFormatConversionException-poikkeuksen
  • Maa-asetuksiin sidotut muotoilijat tuottavat eri tietokoneilla erilaista tulostetta
  • NumberFormat-ilmentymät eivät ole säieturvallisia – luokaa yksi ilmentymä säiettä kohden tai käyttäkää ThreadLocal-luokkaa
// Wrong specifier
try {
    String.format("%d", 3.14); // IllegalFormatConversionException
} catch (java.util.IllegalFormatConversionException e) {
    System.out.println("Wrong format specifier!");
}

// Thread-safe pattern using ThreadLocal
ThreadLocal<NumberFormat> localFmt = ThreadLocal
    .withInitial(() -> NumberFormat.getCurrencyInstance(Locale.US));
// each thread gets its own NumberFormat instance

Pikatarkistus

Mitä String.format("%08.2f", 3.5) tuottaa?

Kertaus: NumberFormat ja printf

Keskeiset opit:

  • String.format / printf käyttävät muotoilumääritteitä: %d, %f, %s, %.2f
  • Leveys- ja tasausliput: %10d (oikealle), %-10d (vasemmalle), %010d (nollatäyttö)
  • NumberFormat.getCurrencyInstance() maa-asetusten mukaiseen valuutan näyttämiseen
  • NumberFormat.getPercentInstance() prosenttitulostukseen
  • DecimalFormat käyttää numeroiden malleissa merkintöjä # (valinnainen) ja 0 (pakollinen)
  • NumberFormat voi myös jäsentää maa-asetusten mukaisesti muotoiltuja merkkijonoja takaisin luvuiksi
Aloita maksutta

Opi Java tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
104
Oppitunnit
374

Usein kysytyt kysymykset

Onko oppitunti ”NumberFormat ja printf” ilmainen?

Kyllä – oppitunnin ”NumberFormat ja printf” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Java Academy-kurssin, päivitä CoddyKit PROhon. Java Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”NumberFormat ja printf”?

Muotoile luvut näyttöä varten NumberFormatin, DecimalFormatin ja printf-mallien avulla. Harjoittelet Java Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Java Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Java Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 4/4.

Kuinka kauan ”NumberFormat ja printf”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Java Academy-oppitunnilla?

Kyllä. Jokainen Java Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Math-luokan perusteet
  2. Kokonaislukulaskenta ja ylivuoto
  3. BigDecimal talouslaskennassa
  4. NumberFormat ja printf
← Takaisin: Java Academy