A DecimalFormat gyakorlati útmutatója

1. Áttekintés

Ebben a cikkben a DecimalFormat osztály gyakorlati felhasználásaival együtt.

Ez a NumberFormat, amely lehetővé teszi a tizedes számok formázását " Húr reprezentáció előre definiált minták felhasználásával.

Fordítottan is használható, a karakterláncok számokba való elemzésére.

2. Hogyan működik?

A szám formázásához meg kell határoznunk egy mintát, amely a szöveggel esetlegesen kevert speciális karakterek sorozata.

11 különleges minta karakter létezik, de a legfontosabbak:

  • 0 - nyomtat egy számjegyet, ha rendelkezésre áll, különben 0
  • # - kinyomtat egy számjegyet, ha van ilyen, különben semmi
  • . - jelezze, hová tegye a tizedes elválasztót
  • , - jelezze, hová tegye a csoportosító elválasztót

Amikor a mintát egy számra alkalmazzák, végrehajtják a formázási szabályait, és az eredményt a DecimalFormatSymbol a JVM-ekből Területi beállítás hacsak nem konkrét Területi beállítás van megadva.

A következő példák kimenetei egy angolul futó JVM-ből származnak Területi beállítás.

3. Alapformázás

Most nézzük meg, hogy mely kimenetek jönnek létre, ha ugyanazt a számot formázzuk a következő mintákkal.

3.1. Egyszerű tizedesjegyek

dupla d = 1234567,89; assertThat (új DecimalFormat ("#. ##"). formátum (d)). isEqualTo ("1234567.89"); assertThat (új DecimalFormat ("0.00"). formátum (d)). isEqualTo ("1234567.89"); 

Mint láthatjuk, az egész részt soha nem vesszük el, függetlenül attól, hogy a minta kisebb-e a számnál.

assertThat (új DecimalFormat ("#########. ###"). formátum (d)). isEqualTo ("1234567.89"); assertThat (új DecimalFormat ("000000000.000"). formátum (d)) .isEqualTo ("001234567.890"); 

Ha ehelyett a minta nagyobb, mint a szám, akkor a nullák hozzáadódnak, míg a kivonatok elesnek mind az egész, mind a tizedes részekben.

3.2. Kerekítés

Ha a minta tizedes része nem tudja tartalmazni a bemeneti szám teljes pontosságát, akkor kerekít.

Itt a .89-es részt 90-re kerekítettük, majd a 0-t eldobtuk:

assertThat (új DecimalFormat ("#. #"). formátum (d)) .isEqualTo ("1234567.9"); 

Itt a .89-es részt 1,00-ra kerekítettük, majd a .00-at eldobtuk, és az 1-et összegeztük a 7-gyel:

assertThat (új DecimalFormat ("#"). formátum (d)) .isEqualTo ("1234568"); 

Az alapértelmezett kerekítési mód HALF_EVEN, de testreszabható a setRoundingMode módszer.

3.3. Csoportosítás

A csoportosító elválasztó segítségével megadható egy olyan alminta, amely automatikusan megismétlődik:

assertThat (új DecimalFormat ("#, ###. #"). formátum (d)) .isEqualTo ("1 234 567,9"); assertThat (új DecimalFormat ("#, ###"). formátum (d)) .isEqualTo ("1 234 568"); 

3.4. Több csoportosítási minta

Egyes országok számozási rendszereiben változó számú csoportosítási minta van.

Az indiai számrendszer a #, ##, ###. ## formátumot használja, amelyben csak az első csoportosító választja el a három számot, míg a többiek két számot.

Ezt nem lehet elérni a DecimalFormat osztály, amely csak a legújabb, balról jobbra tapasztalt mintát tartja, és az egész számra alkalmazza, figyelmen kívül hagyva a korábbi csoportosítási mintákat.

A #, ##, ##, ##, ### minta használatának megkísérlése újracsoportot eredményez a #######, ### és a #, ###, # újraelosztáshoz vezet. ##, ###.

Ahhoz, hogy több csoportosítási mintát egyeztessünk, meg kell írnunk a sajátunkat Húr manipulációs kódot, vagy alternatívaként kipróbálhatja az Icu4J-eket DecimalFormat, amely ezt lehetővé teszi.

3.5. Vonós literálok keverése

Lehet keverni Húr literálák a mintán belül:

assertThat (új DecimalFormat ("A # szám") .formátum (d)) .isEqualTo ("Az 1234568 szám"); 

Speciális karakterek is használhatók Húr literálok, menekülés útján:

assertThat (új DecimalFormat ("A # # # szám") .formátum (d)) .isEqualTo ("A # 1234568 szám"); 

4. Lokalizált formázás

Sok ország nem használ angol szimbólumokat, és a vesszőt használja decimális elválasztóként, a pontot pedig csoportosító elválasztóként.

A #, ###. ## minta futtatása JVM-en olaszral Területi beállításpéldául 1.234.567.89.

Noha ez bizonyos esetekben hasznos lehet az i18n szolgáltatás, más esetekben egy speciális, JVM-től független formátumot érdemes érvényesíteni.

Így tehetjük meg:

assertThat (új DecimalFormat ("#, ###. ##", új DecimalFormatSymbols (Locale.ENGLISH)). format (d)) .isEqualTo ("1 234 567,89"); assertThat (új DecimalFormat ("#, ###. ##", új DecimalFormatSymbols (Locale.ITALIAN)). format (d)) .isEqualTo ("1.234.567,89"); 

Ha a Területi beállítás érdekel, nem tartozik a DecimalFormatSymbols konstruktor, megadhatjuk a getInstance módszer:

Locale customLocale = new Locale ("it", "IT"); assertThat (új DecimalFormat ("#, ###. ##", DecimalFormatSymbols.getInstance (customLocale)). format (d)) .isEqualTo ("1.234.567,89");

5. Tudományos jelölések

A tudományos jelölés egy Mantissa és egy tízes kitevő szorzatát jelenti. A 1234567.89 szám 12.3456789 * 10 ^ 5 néven is ábrázolható (a pontot 5 pozíció tolja el).

5.1. E-Jelölés

Számot lehet kifejezni tudományos jelöléssel a E tízes kitevőt képviselő mintakarakter:

assertThat (új DecimalFormat ("00. ######## E0"). formátum (d)) .isEqualTo ("12.3456789E5"); assertThat (új DecimalFormat ("000.000000E0"). formátum (d)) .isEqualTo ("123.456789E4"); 

Nem szabad megfeledkeznünk arról, hogy az exponens utáni karakterek száma releváns, tehát ha 10 ^ 12-et kell kifejeznünk, akkor E00 és nem E0.

5.2. Mérnöki jelölés

Gyakori a tudományos jelölés egy speciális formája, az úgynevezett mérnöki jelölés, amely az eredményeket úgy állítja be, hogy háromszorossal fejezzék ki, például olyan mérőegységek használatakor, mint a Kilo (10 ^ 3), Mega (10 ^ 6), Giga ( 10 ^ 9), és így tovább.

Kényszeríthetjük ezt a fajta jelölést az egész számjegyek maximális számának (a # és a tizedesválasztó bal oldalán található karakterek) maximális számának beállításával úgy, hogy az nagyobb legyen, mint a minimális szám (a 0-val kifejezve), és magasabb, mint 1.

Ez arra kényszeríti a kitevőt, hogy a maximális szám többszöröse legyen, ezért ehhez a felhasználási esethez azt akarjuk, hogy a maximális szám három legyen:

assertThat (új DecimalFormat ("## 0. ####### E0"). formátum (d)). isEqualTo ("1.23456789E6"); assertThat (új DecimalFormat ("###. 000000E0"). formátum (d)). isEqualTo ("1.23456789E6"); 

6. Elemzés

Nézzük meg, hogyan lehet elemezni a Húr ba be Szám az elemzési módszerrel:

assertThat (új DecimalFormat ("", új DecimalFormatSymbols (Locale.ENGLISH)) .parse ("1234567.89")) .isEqualTo (1234567.89); assertThat (új DecimalFormat ("", új DecimalFormatSymbols (Locale.ITALIAN)) .parse ("1.234.567,89")) .isEqualTo (1234567.89);

Mivel a visszatérő értékre nem következtethet a tizedes elválasztó jelenléte, használhatjuk a következő módszereket: .doubleValue (), .longValue () a visszaküldöttek Szám objektum, hogy érvényesítsen egy adott primitív kimenetet.

Megszerezhetjük a BigDecimal alábbiak szerint:

NumberFormat nf = new DecimalFormat ("", új DecimalFormatSymbols (Locale.ENGLISH)); ((DecimalFormat) nf) .setParseBigDecimal (true); assertThat (nf.parse ("1234567.89")) .isEqualTo (BigDecimal.valueOf (1234567.89)); 

7. Menetbiztonság

DecimalFormat nem szálbiztos, ezért különös figyelmet kell fordítanunk, amikor ugyanazt a példányt megosztjuk a szálak között.

8. Következtetés

Láttuk a DecimalFormat osztály, erősségeivel és gyengeségeivel együtt.

Mint mindig, a teljes forráskód elérhető a Githubon.