Как уже говорилось ранее, «Представление денег в виде двойного числа или числа с плавающей запятой, вероятно, сначала будет хорошо выглядеть, поскольку программное обеспечение округляет крошечные ошибки, но по мере того, как вы будете выполнять дополнительные сложения, вычитания, умножения и деления на неточные числа, вы потеряете большеи больше точности при суммировании ошибок. Это делает поплавки и удвоения неадекватными для работы с деньгами, где требуется идеальная точность для кратных степеням 10 оснований. "
Наконец, в Java есть стандартный способ работыс валютой и деньгами!
JSR 354: API денег и валюты
JSR 354 предоставляет API для представления, транспортировки и выполнения комплексных вычислений с помощью Money иВалюта.Вы можете скачать его по этой ссылке:
JSR 354: Скачать API для денег и валюты
Спецификация состоит из следующих вещей:
- API для обработки, например, денежных сумм и валют
- API для поддержки взаимозаменяемых реализаций
- Фабрики для создания экземпляров классов реализации
- Функциональность для расчетов, преобразования и форматирования денежных сумм
- Java API для работы с деньгами и валютами, который планируется включить в Java 9.
- Все спецификации классов и интерфейсы находятся вjavax.money. * package.
Примеры JSR 354: деньги и валюта API:
Пример создания MonetaryAmount и печатина консоли это выглядит так:
MonetaryAmountFactory<?> amountFactory = Monetary.getDefaultAmountFactory();
MonetaryAmount monetaryAmount = amountFactory.setCurrency(Monetary.getCurrency("EUR")).setNumber(12345.67).create();
MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(Locale.getDefault());
System.out.println(format.format(monetaryAmount));
При использовании эталонного API реализации необходимый код значительно проще:
MonetaryAmount monetaryAmount = Money.of(12345.67, "EUR");
MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(Locale.getDefault());
System.out.println(format.format(monetaryAmount));
APIтакже поддерживает вычисления с MonetaryAmounts:
MonetaryAmount monetaryAmount = Money.of(12345.67, "EUR");
MonetaryAmount otherMonetaryAmount = monetaryAmount.divide(2).add(Money.of(5, "EUR"));
CurrencyUnit и MonetaryAmount
// getting CurrencyUnits by locale
CurrencyUnit yen = MonetaryCurrencies.getCurrency(Locale.JAPAN);
CurrencyUnit canadianDollar = MonetaryCurrencies.getCurrency(Locale.CANADA);
MonetaryAmount имеет различные методы, которые позволяют получить доступ к назначенной валюте, числовой сумме, ее точности и многим другим:
MonetaryAmount monetaryAmount = Money.of(123.45, euro);
CurrencyUnit currency = monetaryAmount.getCurrency();
NumberValue numberValue = monetaryAmount.getNumber();
int intValue = numberValue.intValue(); // 123
double doubleValue = numberValue.doubleValue(); // 123.45
long fractionDenominator = numberValue.getAmountFractionDenominator(); // 100
long fractionNumerator = numberValue.getAmountFractionNumerator(); // 45
int precision = numberValue.getPrecision(); // 5
// NumberValue extends java.lang.Number.
// So we assign numberValue to a variable of type Number
Number number = numberValue;
MonetaryAmounts можно округлить с помощью оператора округления:
CurrencyUnit usd = MonetaryCurrencies.getCurrency("USD");
MonetaryAmount dollars = Money.of(12.34567, usd);
MonetaryOperator roundingOperator = MonetaryRoundings.getRounding(usd);
MonetaryAmount roundedDollars = dollars.with(roundingOperator); // USD 12.35
При работе с коллекциями MonetaryAmounts доступны несколько полезных служебных методов для фильтрации, сортировки и группировки.
List<MonetaryAmount> amounts = new ArrayList<>();
amounts.add(Money.of(2, "EUR"));
amounts.add(Money.of(42, "USD"));
amounts.add(Money.of(7, "USD"));
amounts.add(Money.of(13.37, "JPY"));
amounts.add(Money.of(18, "USD"));
Пользовательские операции MonetaryAmount
// A monetary operator that returns 10% of the input MonetaryAmount
// Implemented using Java 8 Lambdas
MonetaryOperator tenPercentOperator = (MonetaryAmount amount) -> {
BigDecimal baseAmount = amount.getNumber().numberValue(BigDecimal.class);
BigDecimal tenPercent = baseAmount.multiply(new BigDecimal("0.1"));
return Money.of(tenPercent, amount.getCurrency());
};
MonetaryAmount dollars = Money.of(12.34567, "USD");
// apply tenPercentOperator to MonetaryAmount
MonetaryAmount tenPercentDollars = dollars.with(tenPercentOperator); // USD 1.234567
Ресурсы:
Обработка денег и валют в Java с помощью JSR 354
ПросмотрAPI денег и валюты Java 9 (JSR 354)
См. Также: JSR 354 - Валюта и деньги