Dinheiro em Java: Joda-Money, Money
API e além
Otávio Santana
@otaviojava
otaviojava@java.net
otaviojava@apache.org
Double
Float
BigDecimal
Integer
Long
Double e Float
double val = 1.03 - .42;
System.out.println(val); //0.610000000000
0001
Integer e Long
Economia de memória
Velocidade
Chance de dar problemas é alta
Não passar de 8 casas decimais
public class Produto {
private String nome;
private int dinheiro;
//getter and setter
}
Produto banana = new Produto("banana", 1_00);
Produto macarrao = new Produto("macarrao",
1_00);
int total = banana.getDinheiro() +
macarrao.getDinheiro();
BigDecimal
● Maior Controle
● Mais intuitivo
BigDecimal bd1 = new BigDecimal(.01);
//0.01000000000000000020816681...
BigDecimal bd2 = new BigDecimal(.3);
//0.29999999999999998889776975...
BigDecimal total = bd1.add(bd2));
//30999999999999998910593...
public class Produto {
private String nome;
private BigDecimal dinheiro;
//getter and setter
}
Produto caneta = new Produto("caneta",
BigDecimal.valueOf(10.21));
Produto lapis = new Produto("lapis",
BigDecimal.valueOf(12.21));
BigDecimal total =
caneta.getDinheiro().add(lapis.getDinheiro());
Mais desafios para o Dinheiro
● Internacionalização
● Sair na tela
public class Produto {
private String nome;
private String moeda;
private BigDecimal dinheiro;
//getter and setter
}
public class Produto {
private String nome;
private Moeda moeda;
private BigDecimal dinheiro;
//getter and setter
}
enum Moeda {
REAL, DOLLAR, EURO;
}
public class Produto {
private String nome;
private Currency moeda;
private BigDecimal dinheiro;
//getter and setter
}
Currency dollar =
Currency.getInstance(Locale.US);
Currency real = Currency.getInstance("BRL");
Produto celular = //instância;
Produto notebook = //instância;
BigDecimal valor =
celular.getValor().add(notebook.getValor());
Produto celular = //instância;
Produto notebook = //instância;
if(celular.getMoeda().equals(notebook.getMoeda())) {
BigDecimal valor =
celular.getValor().add(notebook.getValor());
}
//exception
public class ProdutoUtils {
public static BigDecimal somar(Produto pA,
Produto pB) {
if(pA.getMoeda().equals(pB.getMoeda())) {
return pA.getValor().add(pB.getValor());
}
return null;
}
}
BigDecimal valor = ProdutoUtils.somar(celular,
notebook);
public class MoneyUtils {
public static BigDecimal somar(Currency
moedaA, BigDecimal valorA, Currency
moedaB, BigDecimal valorB) {
//...
}
public class AssinaturaUtils {}
public class ServicoUtils {}
...
public interface Relatorio {
void printHeader();
void printBody();
void printFooter();
}
Relatorio relatorio = //;
relatorio.printHeader();
relatorio.printBody();
relatorio.printFooter();
public interface Relatorio {
void print();
}
Relatorio relatorio = //;
relatorio.print();
public class Produto {
private String nome;
private Money money;
//getter and setter
}
public class Money extends BigDecimal {
private Currency money;
}
Money valorBanana = new Money("12.00",
dollar);
Money valorAbacaxi = new Money("12.00",
dollar);
Produto banana = new Produto("banana",
valorBanana);
Produto abacaxi = new Produto("abacaxi",
valorAbacaxi);
Money money =
banana.getMoney().add(valorBanana);
public class Mar {
public Sal getSal(){ //...}
public boolean temPeixe() {
return true;
}
//...
}
public class Biscoito extends Mar {
}
public class ClassPai {
public void bug(){
//...
}
//...
}
public class ClasseFilho extends ClassePai {
}
public class Money {
private Currency currency;
private BigDecimal value;
}
Produto banana = new Produto("banana",
valorBanana);
Produto abacaxi = new Produto("abacaxi",
valorAbacaxi);
Money money =
banana.getMoney().add(abacaxi.getMoney());
Joda-Time
JSR 310
Joda-Money
JSR 354
CurrencyUnit usd = CurrencyUnit.of("USD");
Money m = Money.of(usd, 12.43d);
Money money = Money.parse("USD 23.87");
Money result = money.plus(m);
Joda-Money
BigMoney bigMoney = money.toBigMoney();
bigMoney.isGreaterThan(b2);
bigMoney.isLessThan(b2);
bigMoney.isNegativeOrZero();
bigMoney.isPositiveOrZero();
bigMoney.plus(b2);
Joda-Money
Money-API
CurrencyUnit currency =
MonetaryCurrencies.getCurrency(Locale.US);
MonetaryAmount money =
Money.of(BigDecimal.valueOf(10), currency);
MonetaryAmount fastMoney =
FastMoney.of(BigDecimal.valueOf(10), currency);
CurrencyUnit real =
MonetaryCurrencies.getCurrency("BRL");
MonetaryAmount m1 =
Money.of(BigDecimal.valueOf(12D), real);
MonetaryAmount m2 =
Money.of(BigDecimal.valueOf(10D), real);
MonetaryAmount m3 = m1.add(m2);
MonetaryAmount m4 = m1.subtract(m2);
MonetaryAmount m5 = m1.divide(2L);
m1.isLessThan(m2);
m1.isLessThanOrEqualTo(m2);
m1.isGreaterThanOrEqualTo(m2);
m1.isNegative();
m1.isPositive();
m1.isZero();
CurrencyUnit dollar =
MonetaryCurrencies.getCurrency(Locale.US);
MonetaryAmount m = Money.of(120, dollar);
NumberValue number = m.getNumber();
BigDecimal value =
number.numberValue(BigDecimal.class);
MonetaryAmountFormat format =
MonetaryFormats.getAmountFormat(Locale.US);
String texto = format.format(m);//12,50 USD
MonetaryAmount money = Money.parse("EUR
25.25");
MonetaryAmount m2 = Money.parse(texto, format);
MonetaryAmount noMoney = Money.of(0, euro);
MonetaryAmount m1 = Money.of(10, euro);
MonetaryAmount m2 = Money.of(30, euro);
MonetaryAmount m3 = Money.of(40, euro);
List<MonetaryAmount> moneys = Arrays.asList(m1, m2,
m3);
MonetaryAmount sum =
moneys.stream().reduce(MonetaryFunctions.sum()).orEl
se(noMoney);
List<MonetaryAmount> justDollar =
moneys.stream()
.filter((MonetaryFunctions.isCurrency(DOLLAR)))
.collect(Collectors.toList());
List<MonetaryAmount> notEuro =
moneys.stream().filter((MonetaryFunctions.isNotCu
rrency(EURO))).collect(Collectors.toList());
MonetaryFunctions.isCurrency(DOLLAR).and(
MonetaryFunctions.isBetween(min, max)));
MonetaryFunctions.containsCurrencies(EURO,
DOLLAR)).or(MonetaryFunctions.isGreaterTha
n(money)));
List<MonetaryAmount> orderCurrencyValue =
moneys.stream().sorted(MonetaryFunctions.s
ortCurrencyUnit().thenComparing(Monetary
Functions.sortNumber())).collect(Collectors.to
List());
List<MonetaryAmount> orderHighValue =
moneys.stream().sorted(MonetaryFunctions.s
ortCurrencyUnit().thenComparing(
MonetaryFunctions.sortCurrencyUnitDesc()))
.collect(Collectors.toList());
Map<CurrencyUnit, List<MonetaryAmount>>
groupBy =
moneys.stream().collect(MonetaryFunctions.g
roupByCurrencyUnit());
List<MonetaryAmount> notEuro =
moneys.stream().filter((MonetaryFunctions.is
NotCurrency(EURO))).collect(Collectors.toLis
t());
MonetarySummaryStatistics summary =
moneys.stream().collect(MonetaryFunctions.s
ummarizingMonetary(DOLLAR));
GroupMonetarySummaryStatistics
groupSummary =
moneys.stream().collect(MonetaryFunctions.g
roupBySummarizingMonetary());
MonetarySummaryStatistics summary = ...
MonetaryAmount min = summary.getMin();
MonetaryAmount max = summary.getMax();
MonetaryAmount avarage =
summary.getAverage();
Long count = summary.getCount();
MoneyApi
GroupMonetarySummaryStatistics groupSummary =...
Map<CurrencyUnit, MonetarySummaryStatistics> map =
groupSummary.get();
MonetarySummaryStatistics summaryDollar =
map.get(DOLLAR);
CurrencyUnit real = MonetaryCurrencies.getCurrency("BRL");
CurrencyUnit dollar =
MonetaryCurrencies.getCurrency(Locale.US);
MonetaryAmount m1 = Money.of(BigDecimal.valueOf(12D),
real);
MonetaryAmount m2 = Money.of(BigDecimal.valueOf(10D),
dollar);
m1.add(m2);
javax.money.MonetaryException: Currency mismatch:
BRL/USD
ExchangeRateProvider prov =
MonetaryConversions
.getExchangeRateProvider("ECB");
MonetaryAmount d2e =
prov.getCurrencyConversion(euro).apply(mDollar);
ExchangeRateProvider prov =
MonetaryConversions.getExchangeRateProvider
("IMF");
MonetaryAmount d2e =
prov.getCurrencyConversion(euro).apply(mDollar
);
ExchangeRateProvider provider =
MonetaryConversions
.getExchangeRateProvider(ExchangeRateType.
ECB);
ExchangeRateType.ECB
ExchangeRateType.IMF
ExchangeRateType.ECB_HIST90
ExchangeRateType.ECB_HIST
ExchangeRateType.IDENTITY
ExchangeRateProvider provider =
MonetaryConversions
.getExchangeRateProvider(ExchangeRateType.
ECB);
moneys.stream().sorted(MonetaryFunctions.sort
Valuable(provider));
moneys.stream().sorted(MonetaryFunctions.sort
ValuableDesc(provider));
List<MonetaryAmount> orderCurrencyValue =
moneys.stream().sorted(MonetaryFunctions.sortV
aluable(provider).collect(Collectors.toList());
● 9 BRL
● 8 USD
● 7 EUR
● Motivo:
● 1 USD = 2.4203 BRL
● 1 EUR = 4.4203 BRL
● 1 USD = 0.79 EUR
● 7 EUR
● 9 BRL
● 8 USD
MonetarySummaryStatistics summary =
moneys.stream().collect(
MonetaryFunctions.summarizingMonetary(real,
provider));
summary.getCount();
summary.getMax();
summary.getMin();
summary.getAverage();
moneys.stream().reduce(MonetaryFunctions.su
m(provider, dollar));
moneys.stream().reduce(MonetaryFunctions.min
(provider));
moneys.stream().reduce(MonetaryFunctions.ma
x(provider));
Obrigado
Otávio Santana
@otaviojava
otaviojava@java.net
otaviojava@apache.org

Dinheiro em Java: Joda-Money, Money API e além