1. Общ преглед
В този урок ще видим как можем да преобразуваме парична сума в представяне на думи в Java.
Също така ще видим как може да изглежда персонализирана реализация чрез външна библиотека - Tradukisto.
2. Прилагане
Нека първо започнем с нашето собствено изпълнение. Първата стъпка е да декларираме два масива String със следните елементи:
public static String[] ones = { "", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" }; public static String[] tens = { "", // 0 "", // 1 "twenty", // 2 "thirty", // 3 "forty", // 4 "fifty", // 5 "sixty", // 6 "seventy", // 7 "eighty", // 8 "ninety" // 9 };
Когато получим вход, ще трябва да обработим невалидните стойности (нулеви и отрицателни стойности). След като бъде получен валиден вход, можем да извлечем броя долари и центове в променливи:
long dollars = (long) money; long cents = Math.round((money - dollars) * 100);
Ако броят дал е по-малко от 20, а след това ще получите най-подходящите от тях " елемент от масива на базата на индекса:
if (n < 20) { return ones[(int) n]; }
Ще използваме подобен подход за числа под 100, но сега трябва да използваме и десетки масив:
if (n < 100) { return tens[(int) n / 10] + ((n % 10 != 0) ? " " : "") + ones[(int) n % 10]; }
Правим това по подобен начин за числа, по-малки от хиляда.
След това използваме рекурсивни повиквания, за да се справим с номера, по-малки от един милион, както е показано по-долу:
if (n < 1_000_000) { return convert(n / 1000) + " thousand" + ((n % 1000 != 0) ? " " : "") + convert(n % 1000); }
Същият подход се използва за числа, които са по-малко от един милиард и т.н.
Ето основния метод, който може да бъде извикан да направи това преобразуване:
public static String getMoneyIntoWords(double money) { long dollars = (long) money; long cents = Math.round((money - dollars) * 100); if (money == 0D) { return ""; } if (money 0) { dollarsPart = convert(dollars) + " dollar" + (dollars == 1 ? "" : "s"); } String centsPart = ""; if (cents > 0) { if (dollarParts.length() > 0) { centsPart = " and "; } centsPart += convert(cents) + " cent" + (cents == 1 ? "" : "s"); } return dollarsPart + centsPart; }
Нека тестваме нашия код, за да се уверим, че работи:
@Test public void whenGivenDollarsAndCents_thenReturnWords() { String expectedResult = "nine hundred twenty four dollars and sixty cents"; assertEquals( expectedResult, NumberWordConverter.getMoneyIntoWords(924.6)); } @Test public void whenTwoBillionDollarsGiven_thenReturnWords() { String expectedResult = "two billion one hundred thirty three million two hundred" + " forty seven thousand eight hundred ten dollars"; assertEquals( expectedResult, NumberWordConverter.getMoneyIntoWords(2_133_247_810)); } @Test public void whenThirtyMillionDollarsGiven_thenReturnWords() { String expectedResult = "thirty three million three hundred forty eight thousand nine hundred seventy eight dollars"; assertEquals( expectedResult, NumberWordConverter.getMoneyIntoWords(33_348_978)); }
Нека също да тестваме някои крайни случаи и да се уверим, че сме ги обхванали и:
@Test public void whenZeroDollarsGiven_thenReturnEmptyString() { assertEquals("", NumberWordConverter.getMoneyIntoWords(0)); } @Test public void whenNoDollarsAndNineFiveNineCents_thenCorrectRounding() { assertEquals( "ninety six cents", NumberWordConverter.getMoneyIntoWords(0.959)); } @Test public void whenNoDollarsAndOneCent_thenReturnCentSingular() { assertEquals( "one cent", NumberWordConverter.getMoneyIntoWords(0.01)); }
3. Използване на библиотека
Сега, след като внедрихме собствен алгоритъм, нека направим това преобразуване, като използваме съществуваща библиотека.
Tradukisto е библиотека за Java 8+, която може да ни помогне да преобразуваме числата в техните представления на думи. Първо, трябва да го импортираме в нашия проект (най-новата версия на тази библиотека можете да намерите тук):
pl.allegro.finance tradukisto 1.0.1
Сега можем да използваме MoneyConverters е asWords () метод, за да направите това преобразуване:
public String getMoneyIntoWords(String input) { MoneyConverters converter = MoneyConverters.ENGLISH_BANKING_MONEY_VALUE; return converter.asWords(new BigDecimal(input)); }
Нека тестваме този метод с прост тестов случай:
@Test public void whenGivenDollarsAndCents_thenReturnWordsVersionTwo() { assertEquals( "three hundred ten £ 00/100", NumberWordConverter.getMoneyIntoWords("310")); }
Бихме могли да използваме и библиотеката ICU4J, за да направим това, но тя е голяма и се предлага с много други функции, които са извън обхвата на тази статия.
Разгледайте го обаче, ако е необходима поддръжка на Unicode и глобализацията.
4. Заключение
В тази бърза статия видяхме два подхода за това как да превърнем преобразуването на парична сума в думи.
Кодът за всички примери, обяснени тук, и много повече могат да бъдат намерени в GitHub.