Форматиране на числа в Java

1. Общ преглед

В този урок ще разгледаме различни подходи за форматиране на числа в Java и как да ги приложим.

2. Основно форматиране на числа с String # формат

Методът String # format е много полезен за форматиране на числа. Методът взема два аргумента. Първият аргумент описва модела на колко десетични знака искаме да видим, а вторият аргумент е дадената стойност:

double value = 4.2352989244d; assertThat(String.format("%.2f", value)).isEqualTo("4.24"); assertThat(String.format("%.3f", value)).isEqualTo("4.235");

3. Десетично форматиране чрез закръгляване

В Java имаме два примитивни типа, които представляват десетични числа - с плаващо и десетично число :

double myDouble = 7.8723d; float myFloat = 7.8723f;

Броят на десетичните знаци може да бъде различен в зависимост от извършваните операции. В повечето случаи се интересуваме само от първите няколко знака след десетичната запетая. Нека да разгледаме някои начини за форматиране на десетичен знак чрез закръгляване.

3.1. Използване на BigDecimal за форматиране на числа

Класът BigDecimal предоставя методи за закръгляване до определен брой десетични знаци. Нека създадем помощен метод, който ще върне двойно, закръглено до желания брой места:

public static double withBigDecimal(double value, int places) { BigDecimal bigDecimal = new BigDecimal(value); bigDecimal = bigDecimal.setScale(places, RoundingMode.HALF_UP); return bigDecimal.doubleValue(); }

Започваме с нов екземпляр на BigDecimal с оригиналната ни десетична стойност. След това, като задаваме скалата, ние предоставяме желания брой десетични знаци и как искаме да закръглим числото си . Използването на този метод ни позволява лесно да форматираме двойна стойност:

double D = 4.2352989244d; assertThat(withBigDecimal(D, 2)).isEqualTo(4.24); assertThat(withBigDecimal(D, 3)).isEqualTo(4.235);

3.2. Използване на математически # кръг

Също така можем да се възползваме от статичните методи в класа Math, за да закръглим двойна стойност до определен десетичен знак. В този случай можем да коригираме броя на десетичните знаци, като умножим и по-късно разделим с 10 ^ n . Нека проверим нашия помощен метод:

public static double withMathRound(double value, int places) { double scale = Math.pow(10, places); return Math.round(value * scale) / scale; }
assertThat(withMathRound(D, 2)).isEqualTo(4.24); assertThat(withMathRound(D, 3)).isEqualTo(4.235);

Този начин обаче се препоръчва само в определени случаи, тъй като понякога изходът може да бъде закръглен по различен начин, както се очакваше преди да бъде отпечатан.

Това е така, защото Math # round отрязва стойността . Нека да видим как това може да се случи:

System.out.println(withMathRound(1000.0d, 17)); // Gives: 92.23372036854776 !! System.out.println(withMathRound(260.775d, 2)); // Gives: 260.77 instead of expected 260.78 

И така, методът е посочен само за учебни цели.

4. Форматиране на различни типове числа

В някои конкретни случаи може да искаме да форматираме число за определен тип като валута, голямо цяло число или процент.

4.1. Форматиране на големи цели числа със запетаи

Всеки път, когато имаме голямо цяло число в нашето приложение, може да поискаме да го покажем със запетаи, като използваме DecimalFormat с предварително дефиниран шаблон:

public static String withLargeIntegers(double value) { DecimalFormat df = new DecimalFormat("###,###,###"); return df.format(value); } int value = 123456789; assertThat(withLargeIntegers(value)).isEqualTo("123,456,789");

4.2. Попълване на число

В някои случаи може да поискаме да добавим число с нули за определена дължина. Тук можем да използваме метода String # format , както е описано по-рано:

public static String byPaddingZeros(int value, int paddingLength) { return String.format("%0" + paddingLength + "d", value); } int value = 1; assertThat(byPaddingOutZeros(value, 3)).isEqualTo("001");

4.3. Форматиране на числа с две нули след десетичната запетая

За да можем да отпечатаме произволно число с две нули след десетичната запетая, ще използваме още един път клас DecimalFormat с предварително дефиниран шаблон:

public static double withTwoDecimalPlaces(double value) { DecimalFormat df = new DecimalFormat("#.00"); return new Double(df.format(value)); } int value = 12; assertThat(withTwoDecimalPlaces(value)).isEqualTo(12.00);

В този случай създадохме нов формат с шаблон, указващ две нули след десетичната запетая .

4.4. Форматиране и проценти

От време на време може да се наложи да показваме проценти.

В този случай можем да използваме метода NumberFormat # getPercentInstance . Този метод ни позволява да предоставим локал за отпечатване на стойността във формат, който е правилен за държавата, която сте посочили:

public static String forPercentages(double value, Locale locale) { NumberFormat nf = NumberFormat.getPercentInstance(locale); return nf.format(value); } double value = 25f / 100f; assertThat(forPercentages(value, new Locale("en", "US"))).isEqualTo("25%");

4.5. Форматиране на номера на валута

Чест начин за съхраняване на валути в нашето приложение е използването на BigDecimal . Ами ако искаме да ги покажем на потребителя? В този случай можем да използваме класа NumberFormat :

public static String currencyWithChosenLocalisation(double value, Locale locale) { NumberFormat nf = NumberFormat.getCurrencyInstance(locale); return nf.format(value); }

Получаваме екземпляра на валутата за даден Locale и след това просто извикваме метода на формата със стойността. Резултатът е номерът, показан като валута за посочената държава:

double value = 23_500; assertThat(currencyWithChosenLocalisation(value, new Locale("en", "US"))).isEqualTo("$23,500.00"); assertThat(currencyWithChosenLocalisation(value, new Locale("zh", "CN"))).isEqualTo("¥23,500.00"); assertThat(currencyWithChosenLocalisation(value, new Locale("pl", "PL"))).isEqualTo("23 500 zł");

5. Разширено форматиране на случаи на употреба

DecimalFormat е един от най-популярните начини за форматиране на десетично число в Java. Подобно на предишните примери, ще напишем помощен метод:

public static double withDecimalFormatLocal(double value) { DecimalFormat df = (DecimalFormat) NumberFormat.getNumberInstance(Locale.getDefault()); return new Double(df.format(value)); }

Нашият тип форматиране ще получи настройката по подразбиране за дадена локализация.

Десетичното форматиране се обработва по различен начин в различните страни, използвайки техните цифрови системи. Например символът за групиране (запетая в САЩ, но интервал или точка в други локали), размера на групирането (три в САЩ и повечето локали, но различни в Индия) или десетичния знак (точка в САЩ, но запетая в други локали).

double D = 4.2352989244d; assertThat(withDecimalFormatLocal(D)).isEqualTo(4.235);

Също така можем да разширим тази функционалност, за да предоставим някои специфични модели:

public static double withDecimalFormatPattern(double value, int places) { DecimalFormat df2 = new DecimalFormat("#,###,###,##0.00"); DecimalFormat df3 = new DecimalFormat("#,###,###,##0.000"); if (places == 2) return new Double(df2.format(value)); else if (places == 3) return new Double(df3.format(value)); else throw new IllegalArgumentException(); } assertThat(withDecimalFormatPattern(D, 2)).isEqualTo(4.24); assertThat(withDecimalFormatPattern(D, 3)).isEqualTo(4.235);

Тук ние позволяваме на нашия потребител да конфигурира DecimalFormat по избран модел въз основа на броя интервали.

6. Заключение

В тази статия накратко преминахме през различни начини за форматиране на числа в Java. Както виждаме, няма един най-добър начин да се направи това. Могат да се следват много подходи, тъй като всеки от тях има свои собствени характеристики.

Както винаги, кодът за тези примери е достъпен в GitHub.