SlideShare uma empresa Scribd logo
1 de 50
@YourTwitterHandle#Devoxx #YourTag
Introducing JSR 354
The Money & Currency API
Wim van Haaren
Jeroen Burggraaf
www.tritales.nl
#Devoxx #Money @tritales
@YourTwitterHandle#Devoxx #YourTag
About us
Wim van Haaren
Co-founder of Tritales
wim@tritales.nl
jdev.it/blog/
#Devoxx #Money @tritales
Jeroen Burggraaf
Co-founder of Tritales
jeroen@tritales.nl www.tritales.nl
@YourTwitterHandle#Devoxx #YourTag#Devoxx #Money @tritales
Motivation
@YourTwitterHandle#Devoxx #YourTag
Why a Money library?
Martin Fowler:
“A large proportion of the computers in
this world manipulate money, so it’s
always puzzled me that money isn’t
actually a first class data type in any
mainstream programming language. The
lack of a type causes problems, the most
obvious surrounding currencies. …”
http://martinfowler.com/eaaCatalog/money.html
#Devoxx #Money @tritales
@YourTwitterHandle#Devoxx #YourTag
Eric Evans:
“On project after project, software developers have to
reinvent the wheel, creating objects for simple recurring
concepts such as "money" and "currency”…”
http://timeandmoney.sourceforge.net/
#Devoxx #Money @tritales
@YourTwitterHandle#Devoxx #YourTag
Money
• Numerical value
• Currency
#Devoxx #Money @tritales
@YourTwitterHandle#Devoxx #YourTag
Primitive floating types
#Devoxx #Money @tritales
double value = 1.03 - .42;
0.6100000000000001
@YourTwitterHandle#Devoxx #YourTag
Primitive Integer Types
Convert to cents
#Devoxx #Money @tritales
public class Product {
private String name;
private long money;
}
@YourTwitterHandle#Devoxx #YourTag#Devoxx #Money @tritales
Product b1 = new Product(“Westmalle", 5_00);
Product b2 = new Product(“Koninck", 4_00);
900
int sum = b1.getMoney() + b2.getMoney();
@YourTwitterHandle#Devoxx #YourTag
BigDecimal
#Devoxx #Money @tritales
Product b1 = new Product(“Westmalle",
BigDecimal.valueOf(5D));
Product b2 = new Product(“Koninck",
BigDecimal.valueOf(4D));
9.0
BigDecimal sum =
b1.getMoney().add(b2.getMoney());
€ or $ or …?
Currency?
@YourTwitterHandle#Devoxx #YourTag
Currency String
#Devoxx #Money @tritales
public class Product {
private String name;
private String currency;
private BigDecimal money;
}
Type-safety?
Validation?
@YourTwitterHandle#Devoxx #YourTag
Currency Enum
#Devoxx #Money @tritales
public class Product {
private String name;
private Currency currency;
private BigDecimal money;
}
enum Currency {
EURO, POUND, DOLLAR;
}
i18n?
ISO-4217?
@YourTwitterHandle#Devoxx #YourTag
java.util.Currency
• Simple
• Supports ISO-4217
#Devoxx #Money @tritales
public class Product {
private String name;
private Currency currency;
private BigDecimal money;
}
@YourTwitterHandle#Devoxx #YourTag#Devoxx #Money @tritales
Product b1 = new Product(“Westmalle",
Currency.getInstance("EUR"),
BigDecimal.valueOf(5));
Product b2 = new Product(“Koninck",
Currency.getInstance("USD"),
BigDecimal.valueOf(4));
if (b1.getCurrency().equals(b2.getCurrency())) {
// ...
}
@YourTwitterHandle#Devoxx #YourTag
Utility class
#Devoxx #Money @tritales
public static class ProductUtils {
public static BigDecimal sum(Product a,
Product b) {
if(a.getCurrency().equals(b.getCurrency())) {
return a.getValue().add(b.getValue());
}
throw new IllegalArgumentException();
}
}
A lot of Utility classes
Don’t forget to use them
@YourTwitterHandle#Devoxx #YourTag
Money
#Devoxx #Money @tritales
public class Money {
private final BigDecimal value;
private final Currency currency;
// behavior goes here ...
}
@YourTwitterHandle#Devoxx #YourTag#Devoxx #Money @tritales
public class Product {
private String name;
private Money money;
}
Currency euro = Currency.getInstance("EUR");
Product b1 = new Product(“Westmalle”,
new Money(BigDecimal.valueOf(5), euro));
Product b2 = new Product(“Koninck",
new Money(BigDecimal.valueOf(4), euro));
Money money = b1.getMoney().add(b2.getMoney());
@YourTwitterHandle#Devoxx #YourTag
Motivation for Money
• Monetary values are a key feature to many applications
• No standard value type to represent a monetary
amount
• ISO-4217 ambiguous/confusing
• Historical & virtual currencies missing
• Conversions & arithmetic missing
• Formatting missing
#Devoxx #Money @tritales
@YourTwitterHandle#Devoxx #YourTag
JSR 354 – Money and Currency API
• Started 2012 – finalized 2015
• Targeted for JDK 9
• Standalone API:
• Available for JDK 7/8
• Specification (http://javamoney.github.io/api.html)
• RI “Moneta” (http://javamoney.github.io/ri.html)
#Devoxx #Money @tritales
@YourTwitterHandle#Devoxx #YourTag#Devoxx #Money @tritales
Core API
@YourTwitterHandle#Devoxx #YourTag
CurrencyUnit
CurrencyUnit currency =
Monetary.getCurrency("EUR");
CurrencyUnit currency =
Monetary.getCurrency(
new Locale("nl", "NL"));
#Devoxx #Money @tritales
@YourTwitterHandle#Devoxx #YourTag
MonetaryAmount
boolean isGreaterThan(MonetaryAmount amt)
boolean isGreaterThanOrEqualTo(MonetaryAmount amt)
boolean isLessThan(MonetaryAmount amt)
boolean isLessThanOrEqualTo(MonetaryAmount amt)
boolean isEqualTo(MonetaryAmount amt)
boolean isNegative()
boolean isNegativeOrZero()
boolean isPositive()
boolean isPositiveOrZero()
boolean isZero()
#Devoxx #Money @tritales
MonetaryAmount add(MonetaryAmount amt)
MonetaryAmount subtract(MonetaryAmount amt)
MonetaryAmount multiply(Number multiplicand)
MonetaryAmount divide(Number divisor)
MonetaryAmount remainder(Number divisor)
MonetaryAmount negate()
CurrencyUnit getCurrency()
MonetaryAmount with(MonetaryOperator operator)
<R> R query(MonetaryQuery<R> query)
@YourTwitterHandle#Devoxx #YourTag
Creating Money
#Devoxx #Money @tritales
MonetaryAmount money =
MonetaryAmounts.getDefaultAmountFactory()
.setCurrency("EUR")
.setNumber(200.5)
.create();
MonetaryAmount money =
Money.of(200.5, "EUR");
@YourTwitterHandle#Devoxx #YourTag
NumberValue
#Devoxx #Money @tritales
MonetaryAmount m1 = Money.of(10.21, "EUR”);
NumberValue numberValue = m1.getNumber();
NumberValue extends java.lang.Number
 convert to primitive types (long, double, etc.)
@YourTwitterHandle#Devoxx #YourTag#Devoxx #Money @tritales
Operator &
Query
@YourTwitterHandle#Devoxx #YourTag
MonetaryOperator & MonetaryQuery
Functional interfaces
#Devoxx #Money @tritales
public interface MonetaryOperator {
MonetaryAmount apply(MonetaryAmount amount);
}
public interface MonetaryQuery<R>{
R queryFrom(MonetaryAmount amount);
}
@YourTwitterHandle#Devoxx #YourTag#Devoxx #Money @tritales
MonetaryAmount money = Money.of(10, “EUR”);
MonetaryOperator doubleOperator = m -> m.multiply(2);
doubleOperator.apply(money);
// EUR 20.00000
money.with(doubleOperator);
// EUR 20.00000
MonetaryOperator
@YourTwitterHandle#Devoxx #YourTag
MonetaryQuery
#Devoxx #Money @tritales
MonetaryAmount money = Money.of(10, “EUR”);
MonetaryQuery<String> currencyCodeQuery =
m -> m.getCurrency().getCurrencyCode();
currencyCodeQuery.queryFrom(money);
//EUR
money.query(currencyCodeQuery);
//EUR
@YourTwitterHandle#Devoxx #YourTag#Devoxx #Money @tritales
Formatting
@YourTwitterHandle#Devoxx #YourTag
MonetaryAmountFormat
#Devoxx #Money @tritales
public interface MonetaryAmountFormat
extends MonetaryQuery<String> {
AmountFormatContext getContext();
default String format(MonetaryAmount amount) {}
void print(Appendable appendable,
MonetaryAmount amount) throws IOException;
MonetaryAmount parse(CharSequence text)
throws MonetaryParseException;
}
@YourTwitterHandle#Devoxx #YourTag
format()
#Devoxx #Money @tritales
MonetaryAmount money = Money.of(12, “USD”);
MonetaryAmountFormat format =
MonetaryFormats.getAmountFormat(Locale.US);
String s = format.format(money); // USD12.00
@YourTwitterHandle#Devoxx #YourTag
Custom formats
#Devoxx #Money @tritales
CurrencyUnit currency =
Monetary.getCurrency(new Locale("nl", "NL"));
MonetaryAmountFormat patternFormat =
MonetaryAmountDecimalFormatBuilder
.of("¤ ###.###,00")
.withCurrencyUnit(currency)
.build();
MonetaryAmount money = Money.of(12000, currency);
String format = patternFormat.format(money); // € 12.000,00
@YourTwitterHandle#Devoxx #YourTag#Devoxx #Money @tritales
Conversion
@YourTwitterHandle#Devoxx #YourTag
Conversion
#Devoxx #Money @tritales
MonetaryAmount money = Money.of(10,“USD”);
MonetaryAmount money2 = Money.of(10,“EUR”);
MonetaryAmount result = money.add(money2);
javax.money.MonetaryException:
Currency mismatch: USD/EU
“Changing currency by applying exchange rate”
@YourTwitterHandle#Devoxx #YourTag
ExchangeRateProvider
#Devoxx #Money @tritales
MonetaryAmount money = Money.of(10, "EUR");
ExchangeRateProvider provider = MonetaryConversions.
getExchangeRateProvider(ExchangeRateType.ECB);
CurrencyConversion currencyConversion =
provider.getCurrencyConversion("USD");
MonetaryAmount result = currencyConversion.apply(money);
// USD 11.49500
@YourTwitterHandle#Devoxx #YourTag
Exchange rate on a specific date
#Devoxx #Money @tritales
MonetaryAmount money = Money.of(10,“EUR”);
LocalDate localDate = Year.of(2016).atMonth(Month.MAY).atDay(10);
ExchangeRateProvider provider =
MonetaryConversions.getExchangeRateProvider(ExchangeRateType.IMF_HIST);
ConversionQuery query =
ConversionQueryBuilder.of().setTermCurrency(dollar).set(localDate).build();
CurrencyConversion currencyConversion =
provider.getCurrencyConversion(query);
MonetaryAmount result = currencyConversion.apply(money);
// USD 11.37200
@YourTwitterHandle#Devoxx #YourTag#Devoxx #Money @tritales
Streams
@YourTwitterHandle#Devoxx #YourTag
Sorting
#Devoxx #Money @tritales
MonetaryAmount[] m =
{ Money.of(9,"EUR"), Money.of(10,"USD"),
Money.of(11,"GBP"), Money.of(26,"GBP") };
Stream.of(m)
.sorted(MonetaryFunctions.sortCurrencyUnit())
.collect(Collectors.toList());
// [EUR 9, GBP 11, GBP 26, USD 10]
Stream.of(m)
.sorted(MonetaryFunctions.sortNumber())
.collect(Collectors.toList());
// [EUR 9, USD 10, GBP 11, GBP 26] EUR 10 == USD 10
@YourTwitterHandle#Devoxx #YourTag
Sorting using exchange rate
#Devoxx #Money @tritales
MonetaryAmount[] m =
{ Money.of(9,"EUR"),Money.of(10,"USD"),Money.of(7.8,"GBP") };
ExchangeRateProvider provider = MonetaryConversions.
getExchangeRateProvider(ExchangeRateType.IMF);
Stream.of(m)
.sorted(MonetaryFunctions.sortValuable(provider))
.collect(Collectors.toList());
// [USD 10, GBP 7.8, EUR 9]
@YourTwitterHandle#Devoxx #YourTag
Multiple Sorters
#Devoxx #Money @tritales
MonetaryAmount[] m =
{ Money.of(9, "EUR"), Money.of(10, "EUR"),
Money.of(9, "GBP"), Money.of(26,"GBP") };
Stream.of(m).sorted(
sortNumber().thenComparing(sortCurrencyUnit()))
.collect(Collectors.toList());
// [EUR 9, GBP 9, EUR 10, GBP 26]
@YourTwitterHandle#Devoxx #YourTag
Reduction Methods
Predefined higher order functions in the RI Moneta, e.g.:
• MonetaryFunctions.sum()
• MonetaryFunctions.average()
• MonetaryFunctions.min()
• MonetaryFunctions.max()
#Devoxx #Money @tritales
@YourTwitterHandle#Devoxx #YourTag
sum()
#Devoxx #Money @tritales
MonetaryAmount[] money = {
Money.of(10, "USD"),
Money.of(10, "USD"),
Money.of(10, "USD"),
Money.of(9, "USD"),
Money.of(8, "USD")
};
Optional<MonetaryAmount> result =
Stream.of(money)
.reduce(MonetaryFunctions.sum());
// USD 47
@YourTwitterHandle#Devoxx #YourTag#Devoxx #Money @tritales
MonetaryAmount[] money = {
Money.of(10, "USD"),
Money.of(12, "EUR"),
Money.of(15, "USD")};
Optional<MonetaryAmount> result =
Stream.of(money)
.reduce(MonetaryFunctions.sum());
javax.money.MonetaryException:
Currency mismatch: EUR/USD
@YourTwitterHandle#Devoxx #YourTag#Devoxx #Money @tritales
ExchangeRateProvider provider =
MonetaryConversions
.getExchangeRateProvider(ExchangeRateType.IMF);
Stream.of(m1,m2,m3)
.reduce(
MonetaryFunctions.sum(
provider,
Monetary.getCurrency("EUR")));
// € 34.60
@YourTwitterHandle#Devoxx #YourTag
Predicate
#Devoxx #Money @tritales
“Higher order function that operates on a value and returns
a boolean”
Predicates can be used to filter:
Collection<T> filteredCollection =
Stream.of(collection).filter(predicate).collect(Collectors.toList());
Moneta provides predicates:
Predicate<MonetaryAmount> isGreaterThan =
MonetaryFunctions.isGreaterThan(money);
@YourTwitterHandle#Devoxx #YourTag#Devoxx #Money @tritales
Predicates on currency
MonetaryAmount[] m = {Money.of(10, dollar), Money.of(8, euro),
Money.of(9, dollar)};
Stream.of(m).filter(MonetaryFunctions.isCurrency(dollar))
.collect(Collectors.toList());
// [USD 10, USD 9]
Stream.of(m).anyMatch(MonetaryFunctions.isCurrency(dollar));
// true
Stream.of(m).allMatch(MonetaryFunctions.isCurrency(dollar));
// false
@YourTwitterHandle#Devoxx #YourTag#Devoxx #Money @tritales
Predicates on value
MonetaryAmount[] m = {Money.of(10, dollar), Money.of(8, euro),
Money.of(9, dollar)};
Stream.of(m).filter(MonetaryFunctions.isGreaterThan(Money.zero(dollar)))
.collect(Collectors.toList());
// [USD 10, EUR 8, USD 9]
Stream.of(m).anyMatch(MonetaryFunctions.isGreaterThan(Money.zero(dollar)));
// true
@YourTwitterHandle#Devoxx #YourTag
Summarizing Money
#Devoxx #Money @tritales
• Currently no proper money support in the JDK
• JSR 354 fixes this in JDK 9 or as library in JDK 7/8:
• MonetaryAmount class, encapsulates amount & currency
• Operators & queries
• Formatting
• Exchange rate conversions
• Sorting & reduction
• Predicates
@YourTwitterHandle#Devoxx #YourTag
References
• https://www.gitbook.com/book/otaviojava/money-api/details
• https://jcp.org/aboutJava/communityprocess/final/jsr354/index.html
• http://javamoney.github.io/
• http://javamoney.github.io/api.html
• http://javamoney.github.io/ri.html
• http://javamoney.github.io/lib.html
#Devoxx #Money @tritales
@YourTwitterHandle#Devoxx #YourTag#Devoxx #Money @tritales
wim@tritales.nl
jdev.it/blog/
jeroen@tritales.nl
www.tritales.nl
info@tritales.nl
@tritales

Mais conteúdo relacionado

Semelhante a Introducing JSR 354 The Money & Currency API

Event Sourcing - You are doing it wrong @ Devoxx
Event Sourcing - You are doing it wrong @ DevoxxEvent Sourcing - You are doing it wrong @ Devoxx
Event Sourcing - You are doing it wrong @ DevoxxDavid Schmitz
 
What Web Developers Need to Know to Develop Windows 8 Apps
What Web Developers Need to Know to Develop Windows 8 AppsWhat Web Developers Need to Know to Develop Windows 8 Apps
What Web Developers Need to Know to Develop Windows 8 AppsDoris Chen
 
WCRI 2015 I18N L10N
WCRI 2015 I18N L10NWCRI 2015 I18N L10N
WCRI 2015 I18N L10NDave McHale
 
Project: Call Center Management
Project: Call Center ManagementProject: Call Center Management
Project: Call Center Managementpritamkumar
 
flutteragency-com-handling-events-and-user-input-in-flutter-.pdf
flutteragency-com-handling-events-and-user-input-in-flutter-.pdfflutteragency-com-handling-events-and-user-input-in-flutter-.pdf
flutteragency-com-handling-events-and-user-input-in-flutter-.pdfFlutter Agency
 
Creating a Facebook Clone - Part V - Transcript.pdf
Creating a Facebook Clone - Part V - Transcript.pdfCreating a Facebook Clone - Part V - Transcript.pdf
Creating a Facebook Clone - Part V - Transcript.pdfShaiAlmog1
 
Html5 and web technology update
Html5 and web technology updateHtml5 and web technology update
Html5 and web technology updateDoug Domeny
 
5 x HTML5 worth using in APEX (5)
5 x HTML5 worth using in APEX (5)5 x HTML5 worth using in APEX (5)
5 x HTML5 worth using in APEX (5)Christian Rokitta
 
Adopting F# at SBTech
Adopting F# at SBTechAdopting F# at SBTech
Adopting F# at SBTechAntya Dev
 
JSR 354 Hackday - What you can do...
JSR 354 Hackday - What you can do...JSR 354 Hackday - What you can do...
JSR 354 Hackday - What you can do...Anatole Tresch
 
ProTips DroidCon Paris 2013
ProTips DroidCon Paris 2013ProTips DroidCon Paris 2013
ProTips DroidCon Paris 2013Mathias Seguy
 
Boost Your Development With Proper API Design
Boost Your Development With Proper API DesignBoost Your Development With Proper API Design
Boost Your Development With Proper API DesignMarcusHeld1
 
Web automation with #d8rules (European Drupal Days 2015)
Web automation with #d8rules (European Drupal Days 2015)Web automation with #d8rules (European Drupal Days 2015)
Web automation with #d8rules (European Drupal Days 2015)Eugenio Minardi
 
I18n
I18nI18n
I18nsoon
 
Hack it like its hot!
Hack it like its hot!Hack it like its hot!
Hack it like its hot!Stefan Adolf
 

Semelhante a Introducing JSR 354 The Money & Currency API (20)

Introduccion a HTML5
Introduccion a HTML5Introduccion a HTML5
Introduccion a HTML5
 
html5
html5html5
html5
 
Event Sourcing - You are doing it wrong @ Devoxx
Event Sourcing - You are doing it wrong @ DevoxxEvent Sourcing - You are doing it wrong @ Devoxx
Event Sourcing - You are doing it wrong @ Devoxx
 
What Web Developers Need to Know to Develop Windows 8 Apps
What Web Developers Need to Know to Develop Windows 8 AppsWhat Web Developers Need to Know to Develop Windows 8 Apps
What Web Developers Need to Know to Develop Windows 8 Apps
 
WCRI 2015 I18N L10N
WCRI 2015 I18N L10NWCRI 2015 I18N L10N
WCRI 2015 I18N L10N
 
Project: Call Center Management
Project: Call Center ManagementProject: Call Center Management
Project: Call Center Management
 
flutteragency-com-handling-events-and-user-input-in-flutter-.pdf
flutteragency-com-handling-events-and-user-input-in-flutter-.pdfflutteragency-com-handling-events-and-user-input-in-flutter-.pdf
flutteragency-com-handling-events-and-user-input-in-flutter-.pdf
 
Creating a Facebook Clone - Part V - Transcript.pdf
Creating a Facebook Clone - Part V - Transcript.pdfCreating a Facebook Clone - Part V - Transcript.pdf
Creating a Facebook Clone - Part V - Transcript.pdf
 
Html5 and web technology update
Html5 and web technology updateHtml5 and web technology update
Html5 and web technology update
 
5 x HTML5 worth using in APEX (5)
5 x HTML5 worth using in APEX (5)5 x HTML5 worth using in APEX (5)
5 x HTML5 worth using in APEX (5)
 
Dartprogramming
DartprogrammingDartprogramming
Dartprogramming
 
Adopting F# at SBTech
Adopting F# at SBTechAdopting F# at SBTech
Adopting F# at SBTech
 
JSR 354 LJC-Hackday
JSR 354 LJC-HackdayJSR 354 LJC-Hackday
JSR 354 LJC-Hackday
 
JSR 354 Hackday - What you can do...
JSR 354 Hackday - What you can do...JSR 354 Hackday - What you can do...
JSR 354 Hackday - What you can do...
 
ProTips DroidCon Paris 2013
ProTips DroidCon Paris 2013ProTips DroidCon Paris 2013
ProTips DroidCon Paris 2013
 
Boost Your Development With Proper API Design
Boost Your Development With Proper API DesignBoost Your Development With Proper API Design
Boost Your Development With Proper API Design
 
Web automation with #d8rules (European Drupal Days 2015)
Web automation with #d8rules (European Drupal Days 2015)Web automation with #d8rules (European Drupal Days 2015)
Web automation with #d8rules (European Drupal Days 2015)
 
Jquery fundamentals
Jquery fundamentalsJquery fundamentals
Jquery fundamentals
 
I18n
I18nI18n
I18n
 
Hack it like its hot!
Hack it like its hot!Hack it like its hot!
Hack it like its hot!
 

Último

Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 

Último (20)

Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 

Introducing JSR 354 The Money & Currency API

Notas do Editor

  1. Good afternoon everybody and welcome to our talk about JSR 354 – The Money and Currency API.
  2. First of all, who are we? Well, my name is Wim van Haaren… … and my name is Jeroen Burggraaf. We are the founders of Tritales, a company in the Netherlands. Together we have over 35 years of software development experience in both backend as well as frontend development. Lets start with our talk about the money and currency API.
  3. Let’s quickly get to the reason why we are standing here. Why do we want to talk about a JSR about Money and Currency?
  4. Well, a lot of applications have to deal with money. So why do the mainstream programming languages not provide data types for it? Especially since this has caused of lots of problems…
  5. Furthermore, we as programmers keep on reinventing the wheel over and over again… To show some of the problems we could run into, we are going to start by having a look at how in the past we would typically go about dealing with money.
  6. I guess you all know, that money is made up of two parts: it has a numerical value and it has a currency. But since the JDK doesn't provide a standard representation of money, how could we as developers represent it?
  7. As a beginning developer our first attempt would probably to use a double. <KLIK> But then the output would not be quite what we expected. <KLIK> So, are floating points broken in Java? No, it's not, but this is how IEEE-754 standard works.
  8. Let’s use integer types as our next attempt. If we are using a long, we will first have to convert the value of our money to cents. However, this solution does have some problems with readability and flexibility. Let’s say for example that we’ve got a Product class with a name and a value attribute.
  9. And suppose we have two products defined somewhere in our system. <KLIK> And somewhere our colleague is going to sum up the two values. <KLIK> As you can imagine, it is very easy to go wrong with this design where we could easily forget the fact that we have to convert euros into cents.
  10. Lets rewrite the last example using BigDecimal. BigDecimal makes our lives easier because it sounds more natural to say that a product is worth 9 euros rather than 900 cents. <KLIK> Now our co-worker won’t be confused about the value. So this is exactly what we want. However, there is a very important factor missing in our design. <KLIK> Because most of the time, the number 9 has no real meaning without a currency.
  11. If our program deals with a single currency then we are totally fine and we don’t need to model currencies. However, this is not the case most of the time. So let's add a field of type String to hold the currency. Well, this is clearly not a good design because it's not type-safe. The String is not validated and could be anything that is not a valid currency.
  12. We can make the currency type-safe by introducing an enum. Now we have a fixed set of currencies so we cannot use an incorrect currency. The enum, however, is still very limited and lacks various aspects like internationalization and standardization like ISO-4217. ISO 4217 is an international standard that represents currencies as 3-character codes.
  13. A more advanced approach is to use the java.util.Currency class which is available in the JDK. It is type-safe and support the ISO currency standard. So we improve our product design by using it.
  14. A Currency can be instantiated by providing an ISO currency code. So now we have a suitable amount and currency type.
  15. However, to make it useful we need operations like addition, subtraction etc. and we need to take into account that the currencies of our two products might be different so it is essential to do some validation before operating on the amount values. We will end up with a lot of utility classes and it is important not to forget to use them.
  16. Adding an abstraction for representing money becomes more and more obvious after we try all these tricks. Martin Fowler wrote an article describing an abstraction for representing money that solves the issues we have seen. This Money class should be the only type that is responsible for dealing with money and encapsulates the amount and currency and provides utility operations.
  17. So let’s use this Money class and add it to the product. <<click>> Next we instantiate our products by providing a Money instances… <<click>> and now we can apply operations on the money instances. This raises the question why such a Money class is still not available in the JDK yet.
  18. Let’s summarize the motivation to add a Money class. Monetary amounts are a key feature of many applications and there is no standard type yet. There are some quirks with ISO 4217. It contains some ambiguous currency codes like the central African franc which has two variants used in different areas. Furthermore, historical currencies are missing. Virtual currencies like Bitcoin are not supported. Conversion and arithmetic is missing. Formatting is not provided.
  19. So we have seen problems and missing functionality in the JDK. This lead to the development of JSR 354, the money and currency API which started in 2012 and was finished in 2015. The new JSR is targeted for JDK 9. A standalone API will be available which can be used in JDK 7 and 8 in combination with the ‘Moneta’ reference implementation. Wim will now talk about the details of this new API.
  20. So let’s have a closer look at the JSR 354 Specification. As we’ve seen Money is represented by a value and by its currency.
  21. Currencies are represented by the CurrencyUnit interface. And implementations of this interface are required to be immutable and thread-safe A CurrencyUnit can be constructed in a multitude of ways. The easiest two ways are using the Currency code, which is a three character string. Or by passing in the Locale.
  22. Amounts are represented by the MonetaryAmount interface. Again, implementations are required to be immutable and thread-safe   There are alotof methods defined by the interface. But bascially there are four groups. 1) boolean operators like isGreatherThan() or isPositive(). 2) arithmetic operator methods like add() and divide(). 3) a method to get the Currency for this amount. 4) finally there is the query() method about which Jeroen will tell you more in a minute.
  23. Amounts are generated using a MontaryAmountFactory. The simplest case, you would use the default factory. <klik> But using the RI Moneta, creating money is even simpler. Just call one of the static methods and provide it with a value and a currency
  24. To retrieve the numerical value of a money amount, all you have to do is call the method getNumber() which will return a NumberValue object. NumberValue extends java.lang.Number and as a result it can easily be converted to primitive numerical types (e.g. int , long , float , double , short , byte ).
  25. Let’s talk about monetary operators and queries.
  26. The JSR provides two functional interfaces: MonetaryOperator and MonetaryQuery. MonetaryOperator takes a monetary amount, operates on it and produces a new monetary amount. MonetaryQuery provides queries for example for retrieving the fractional parts (cents). Both MonetaryOperator and MonetaryQuery can be instantiated using a lamba expression.
  27. The Monetary operator accepts a monetary amount and returns a new monetary amount. In this example we create an amount of 10 euro’s which we want to multiply by 2. We create a monetary operator to do this. There are two ways to apply it, either use the ‘apply’ method of the operator with the amount as argument or use the ‘with’ method of the amount with the operator as argument.
  28. Similar to MonetaryOperator, MonetaryQuery is a functional interface. It accepts a monetary amount and returns a generic type. You can perform queries on a monetary amount such as getting the currency code or the number of fraction digits. Again there are two ways to apply it.
  29. One of the goals of the JSR was to make formatting simple and flexible, and to overcome problems with the current Java formatting options, especially the lack of thread safety.
  30. To do so, the MonetaryAmountFormat was introduced. There are several methods defined by the interface but for now we’ll take a quick look at format().
  31. Converting a MonetaryAmount to a textual representation is very easy. Just get your hands on a formatter from the MonetaryFormats singelton, and then call the format() method on it… For more control over the formatting you can also use QueryBuilders….
  32. If the standard formats don’t suit you, you can always use custom formats. Here we see one possible example using a DecimalFormatQueryBuilder.
  33. Conversion is the process of changing the currency of a monetary amount by applying an exchange rate. The exchange rate is the ratio between one currency and the other. The process of conversion is important when dealing with different international countries and currencies. As an example, let’s try to add two amounts with different currencies. What happens? <<click>> A MonetaryException is raised since the currencies don’t match. So before we can add these amounts, we have to make sure both amounts have the same currency by applying an exchange rate.
  34. In order to apply an exchange rate we use an exchange rate provider. In this example we create such a provider and then apply it to the euro amount to convert it to a US dollar amount. After this we can add the two amounts without an exception. The exchange rate in this example is retrieved from the European Central Bank. It is also possible to retrieve the exchange rates from the International Monetary Fund and to get the currency on historic dates.
  35. As an example we use the date of May 10th 2016 and try to get the exchange rate to convert to a US dollar amount. Fortunately this day is on a Tuesday and an exchange rate is available, otherwise an exception would have been thrown.
  36. JSR354 was developed under Java 8, and so it uses Java 8 functionality alot. The RI Moneta provides some higher order functions in the MonetaryFunctions class that help you when working with Streams. Let’s have a look at some examples…
  37. There are several functions available for sorting. Here, we see an example to sort alphabetically, and another to sort by the value. These sorting functions will not factor in exchange rates. In other words, ten Euros will be considered equal to ten US Dollars.
  38. To sort based on the exchange rate, an ExchangeRateProvider must be provided.
  39. TODO OUTPUT It is also possible to combine multiple sorters. The Comparator.thenComparing() method can be used to chain multiple sorting comparators. Essentially, the secondary comparator will be applied when two values are equal according to the first comparator.
  40. Reduce, also known as fold , is a higher order function that, when applied on a stream, results in a value or none. For example, sum, average, min, and max. As an example we’ll take a look at sum(). The average(), min() and max() methods work similarly.
  41. Sum is a reduction method. Given a stream of MonetaryAmount, it returns the sum of its elements.
  42. If we want to sum up amounts with different currencies, an exception will be thrown to signal that a currency mismatch has occured.
  43. To avoid that, an ExchangeRateProvider must be provided. And now we can sum up amounts with different currencies.
  44. Let’s talk about predicates. As you will remember, a predicate is a higher order function that takes a value and results in a Boolean. It can be used for filtering a collection. The moneta reference implementation provides several predicates on a monetary amount value or currency.
  45. Here we show some example of currency predicates. We create an array of two US dollar amounts and one euro amount. We use an isCurrency predicate to get all US dollar amounts. Next a predicate to determine if there is at least one US dollar amount in the collection and a predicate to determine if all amounts in the collection are US dollar amounts.
  46. Next we show a couple of predicates that act on the monetary amount value. Again we create an array of monetary amounts and filter on amounts greater than zero. We also use a matcher to verify that there is at least one amount greater than zero.
  47. We’ve reached the end of our presentation about the money and currency API. We will summarize what we have discussed. We saw that there is currently no proper support for monetary amounts in the JDK. JSR 354 fixes this in JDK 9. For JDK 8 and before a standalone API is provided that can be used in combination with the moneta reference implementation. The JSR provides a monetary amount class, monetary operators and queries, formatters, conversions, sorting, reduction, predicates, grouping and filtering.
  48. Of course these 15 minutes are too short to cover the complete JSR. The following references provide more information about the money and currency API. Soon after the conference we will make the presentation available on slideshare. Visit our website for the link.
  49. Thanks for attending our presentation. If you have any questions please come over to discuss them.