日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

Java 9中新的貨幣API

瀏覽:94日期:2022-09-06 11:10:07

JSR 354定義了一套新的Java貨幣API,計劃會在Java 9中正式引入。本文中我們將來看一下它的參考實現:JavaMoney的當前進展。

正如我在之前那篇Java 8新的日期時間API一文中那樣,本文主要也是通過一些代碼來演示下新的API的用法 。

在開始之前,我想先用一段話來簡短地總結一下規范定義的這套新的API的用意何在:

對許多應用而言貨幣價值都是一個關鍵的特性,但JDK對此卻幾乎沒有任何支持。嚴格來講,現有的java.util.Currency類只是代表了當前ISO 4217貨幣的一個數據結構,但并沒有關聯的值或者自定義貨幣。JDK對貨幣的運算及轉換也沒有內建的支持,更別說有一個能夠代表貨幣值的標準類型了。

如果你用的是Maven的話,只需把下面的引用添加到工里面便能夠體驗下該參考實現的當前功能了:

<dependency> <groupId>org.javamoney</groupId> <artifactId>moneta</artifactId> <version>0.9</version></dependency>

規范中提到的類及接口都在javax.money.*包下面。

我們先從核心的兩個接口CurrencyUnit與MonetaryAmount開始講起。

CurrencyUnit及MonetaryAmount

CurrencyUnit代表的是貨幣。它有點類似于現在的java.util.Currency類,不同之處在于它支持自定義的實現。從規范的定義來看,java.util.Currency也是可以實現該接口的。CurrencyUnit的實例可以通過MonetaryCurrencies工廠來獲取:

// 根據貨幣代碼來獲取貨幣單位 CurrencyUnit euro = MonetaryCurrencies.getCurrency("EUR"); CurrencyUnit usDollar = MonetaryCurrencies.getCurrency("USD"); // 根據國家及地區來獲取貨幣單位 CurrencyUnit yen = MonetaryCurrencies.getCurrency(Locale.JAPAN); CurrencyUnit canadianDollar = MonetaryCurrencies.getCurrency(Locale.CANADA);

MontetaryAmount代表的是某種貨幣的具體金額。通常它都會與某個CurrencyUnit綁定。

MontetaryAmount和CurrencyUnit一樣,也是一個能支持多種實現的接口。

CurrencyUnit與MontetaryAmount的實現必須是不可變,線程安全且可比較的。

/ get MonetaryAmount from CurrencyUnitCurrencyUnit euro = MonetaryCurrencies.getCurrency("EUR");MonetaryAmount fiveEuro = Money.of(5, euro); // get MonetaryAmount from currency codeMonetaryAmount tenUsDollar = Money.of(10, "USD"); // FastMoney is an alternative MonetaryAmount factory that focuses on performanceMonetaryAmount sevenEuro = FastMoney.of(7, euro);

Money與FastMoney是JavaMoney庫中MonetaryAmount的兩種實現。Money是默認實現,它使用BigDecimal來存儲金額。FastMoney是可選的另一個實現,它用long類型來存儲金額。根據文檔來看,FastMoney上的操作要比Money的快10到15倍左右。然而,FastMoney的金額大小與精度都受限于long類型。

注意了,這里的Money和FastMoney都是具體的實現類(它們在org.javamoney.moneta.*包下面,而不是javax.money.*)。如果你不希望指定具體類型的話,可以通過MonetaryAmountFactory來生成一個MonetaryAmount的實例:

MonetaryAmount specAmount = MonetaryAmounts.getDefaultAmountFactory().setNumber(123.45) .setCurrency("USD") .create();

當且僅當實現類,貨幣單位,以及數值全部相等時才認為這兩個MontetaryAmount實例是相等的。

MonetaryAmount oneEuro = Money.of(1, MonetaryCurrencies.getCurrency("EUR"));boolean isEqual = oneEuro.equals(Money.of(1, "EUR")); // trueboolean isEqualFast = oneEuro.equals(FastMoney.of(1, "EUR")); // false

MonetaryAmount內包含豐富的方法,可以用來獲取具體的貨幣,金額,精度等等:

MonetaryAmount monetaryAmount = Money.of(123.45, euro);CurrencyUnit currency = monetaryAmount.getCurrency();NumberValue numberValue = monetaryAmount.getNumber(); int intValue = numberValue.intValue(); // 123double doubleValue = numberValue.doubleValue(); // 123.45long fractionDenominator = numberValue.getAmountFractionDenominator(); // 100long fractionNumerator = numberValue.getAmountFractionNumerator(); // 45int precision = numberValue.getPrecision(); // 5 // NumberValue extends java.lang.Number. // So we assign numberValue to a variable of type NumberNumber number = numberValue;

MonetaryAmount的使用

可以在MonetaryAmount上進行算術運算:

MonetaryAmount twelveEuro = fiveEuro.add(sevenEuro); // "EUR 12"MonetaryAmount twoEuro = sevenEuro.subtract(fiveEuro); // "EUR 2"MonetaryAmount sevenPointFiveEuro = fiveEuro.multiply(1.5); // "EUR 7.5" // MonetaryAmount can have a negative NumberValueMonetaryAmount minusTwoEuro = fiveEuro.subtract(sevenEuro); // "EUR -2" // some useful utility methodsboolean greaterThan = sevenEuro.isGreaterThan(fiveEuro); // trueboolean positive = sevenEuro.isPositive(); // trueboolean zero = sevenEuro.isZero(); // false // Note that MonetaryAmounts need to have the same CurrencyUnit to do mathematical operations// this fails with: javax.money.MonetaryException: Currency mismatch: EUR/USDfiveEuro.add(tenUsDollar);

舍入操作是金額換算里面非常重要的一部分。MonetaryAmount可以使用舍入操作符來進行四舍五入:

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

這里12.3456美金就會按當前貨幣默認的舍入規則來進行換算。

在操作MonetaryAmount集合時,有許多實用的工具方法可以用來進行過濾,排序以及分組。這些方法還可以與Java 8的流API一起配套使用。

看一下下面這個集合:

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"));

我們可以根據CurrencyUnit來進行金額過濾:

CurrencyUnit yen = MonetaryCurrencies.getCurrency("JPY");CurrencyUnit dollar = MonetaryCurrencies.getCurrency("USD");// 根據貨幣過濾,只返回美金// result is [USD 18, USD 7, USD 42]List<MonetaryAmount> onlyDollar = amounts.stream() .filter(MonetaryFunctions.isCurrency(dollar)) .collect(Collectors.toList()); // 根據貨幣過濾,只返回美金和日元// [USD 18, USD 7, JPY 13.37, USD 42]List<MonetaryAmount> onlyDollarAndYen = amounts.stream() .filter(MonetaryFunctions.isCurrency(dollar, yen)) .collect(Collectors.toList());

我們還可以過濾出大于或小于某個閾值的金額:

MonetaryAmount tenDollar = Money.of(10, dollar); // [USD 42, USD 18]List<MonetaryAmount> greaterThanTenDollar = amounts.stream() .filter(MonetaryFunctions.isCurrency(dollar)) .filter(MonetaryFunctions.isGreaterThan(tenDollar)) .collect(Collectors.toList());

排序也是類似的:

// Sorting dollar values by number value// [USD 7, USD 18, USD 42]List<MonetaryAmount> sortedByAmount = onlyDollar.stream() .sorted(MonetaryFunctions.sortNumber()) .collect(Collectors.toList()); // Sorting by CurrencyUnit// [EUR 2, JPY 13.37, USD 42, USD 7, USD 18]List<MonetaryAmount> sortedByCurrencyUnit = amounts.stream() .sorted(MonetaryFunctions.sortCurrencyUnit()) .collect(Collectors.toList());

還有分組操作:

// 按貨幣單位進行分組// {USD=[USD 42, USD 7, USD 18], EUR=[EUR 2], JPY=[JPY 13.37]}Map<CurrencyUnit, List<MonetaryAmount>> groupedByCurrency = amounts.stream() .collect(MonetaryFunctions.groupByCurrencyUnit()); // 分組并進行匯總Map<CurrencyUnit, MonetarySummaryStatistics> summary = amounts.stream() .collect(MonetaryFunctions.groupBySummarizingMonetary()).get(); // get summary for CurrencyUnit USDMonetarySummaryStatistics dollarSummary = summary.get(dollar);MonetaryAmount average = dollarSummary.getAverage(); // "USD 22.333333333333333333.."MonetaryAmount min = dollarSummary.getMin(); // "USD 7"MonetaryAmount max = dollarSummary.getMax(); // "USD 42"MonetaryAmount sum = dollarSummary.getSum(); // "USD 67"long count = dollarSummary.getCount(); // 3

MonetaryFunctions還提供了歸約函數,可以用來獲取最大值,最小值,以及求和:

List<MonetaryAmount> amounts = new ArrayList<>();amounts.add(Money.of(10, "EUR"));amounts.add(Money.of(7.5, "EUR"));amounts.add(Money.of(12, "EUR")); Optional<MonetaryAmount> max = amounts.stream().reduce(MonetaryFunctions.max()); // "EUR 7.5"Optional<MonetaryAmount> min = amounts.stream().reduce(MonetaryFunctions.min()); // "EUR 12"Optional<MonetaryAmount> sum = amounts.stream().reduce(MonetaryFunctions.sum()); //

自定義的MonetaryAmount操作

MonetaryAmount還提供了一個非常友好的擴展點叫作MonetaryOperator。MonetaryOperator是一個函數式接口,它接收一個MonetaryAmount入參并返回一個新的MonetaryAmount對象。

// A monetary operator that returns 10% of the input MonetaryAmount// Implemented using Java 8 LambdasMonetaryOperator 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 MonetaryAmountMonetaryAmount tenPercentDollars = dollars.with(tenPercentOperator); // USD 1.234567

標準的API特性都是通過MonetaryOperator的接口來實現的。比方說,前面看到的舍入操作就是以MonetaryOperator接口的形式來提供的。

匯率

貨幣兌換率可以通過ExchangeRateProvider來獲取。JavaMoney自帶了多個不同的ExchangeRateProvider的實現。其中最重要的兩個是ECBCurrentRateProvider與 IMFRateProvider。

ECBCurrentRateProvider查詢的是歐洲中央銀行(European Central Bank,ECB)的數據而IMFRateProvider查詢的是國際貨幣基金組織(International Monetary Fund,IMF)的匯率。

// get the default ExchangeRateProvider (CompoundRateProvider)ExchangeRateProvider exchangeRateProvider = MonetaryConversions.getExchangeRateProvider(); // get the names of the default provider chain// [IDENT, ECB, IMF, ECB-HIST]List<String> defaultProviderChain = MonetaryConversions.getDefaultProviderChain(); // get a specific ExchangeRateProvider (here ECB)ExchangeRateProvider ecbExchangeRateProvider = MonetaryConversions.getExchangeRateProvider("ECB");

如果沒有指定ExchangeRateProvider的話返回的就是CompoundRateProvider。CompoundRateProvider會將匯率轉換請求委派給一個ExchangeRateProvider鏈并將第一個返回準確結果的提供商的數據返回。

// get the exchange rate from euro to us dollarExchangeRate rate = exchangeRateProvider.getExchangeRate("EUR", "USD"); NumberValue factor = rate.getFactor(); // 1.2537 (at time writing)CurrencyUnit baseCurrency = rate.getBaseCurrency(); // EURCurrencyUnit targetCurrency = rate.getCurrency(); // USD

貨幣轉換

不同貨幣間的轉換可以通過ExchangeRateProvider返回的CurrencyConversions來完成。

// get the CurrencyConversion from the default provider chainCurrencyConversion dollarConversion = MonetaryConversions.getConversion("USD"); // get the CurrencyConversion from a specific providerCurrencyConversion ecbDollarConversion = ecbExchangeRateProvider.getCurrencyConversion("USD"); MonetaryAmount tenEuro = Money.of(10, "EUR"); // convert 10 euro to us dollar MonetaryAmount inDollar = tenEuro.with(dollarConversion); // "USD 12.537" (at the time writing)

請注意CurrencyConversion也實現了MonetaryOperator接口。正如其它操作一樣,它也能通過MonetaryAmount.with()方法來調用。

格式化及解析

MonetaryAmount可以通過MonetaryAmountFormat來與字符串進行解析/格式化。

// formatting by locale specific formatsMonetaryAmountFormat germanFormat = MonetaryFormats.getAmountFormat(Locale.GERMANY);MonetaryAmountFormat usFormat = MonetaryFormats.getAmountFormat(Locale.CANADA); MonetaryAmount amount = Money.of(12345.67, "USD"); String usFormatted = usFormat.format(amount); // "USD12,345.67"String germanFormatted = germanFormat.format(amount); // 12.345,67 USD // A MonetaryAmountFormat can also be used to parse MonetaryAmounts from stringsMonetaryAmount parsed = germanFormat.parse("12,4 USD");

可以通過AmountFormatQueryBuilder來生成自定義的格式。

// Creating a custom MonetaryAmountFormatMonetaryAmountFormat customFormat = MonetaryFormats.getAmountFormat( AmountFormatQueryBuilder.of(Locale.US).set(CurrencyStyle.NAME).set("pattern", "00,00,00,00.00 ¤").build()); // results in "00,01,23,45.67 US Dollar"String formatted = customFormat.format(amount);

注意,這里的¤符號在模式串中是作為貨幣的占位符。

總結

新的貨幣API這里已經介紹得差不多了。并且目前它的實現也已經相對穩定了(但還需要多補充些文檔)。期待能在Java 9中看到這套新的接口!

上述示例可在Github中下載到。

原文出處:Michael Scharhag

標簽: Java
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日韩久久精品网| 亚洲日韩中文字幕一区| 国产精品毛片在线看| 亚洲黄色网址| 久久国产乱子精品免费女| 日韩精品免费视频一区二区三区| 九一精品国产| 午夜电影一区| 欧美中文高清| 国产日韩欧美一区二区三区| 91精品在线免费视频| 成人免费电影网址| 亚洲黄色在线| 日韩专区视频网站| 国产乱人伦精品一区| 97精品国产福利一区二区三区| 亚洲精品a级片| 日韩欧美一区二区三区在线视频| 青青草国产精品亚洲专区无| 国产日韩欧美| 精品淫伦v久久水蜜桃| 亲子伦视频一区二区三区| 国产亚洲精品久久久久婷婷瑜伽| 欧美一区网站| 国产国产精品| 国产精品久久久久久妇女| 欧美日韩视频免费观看| 美女久久一区| 成人久久久久| 福利片在线一区二区| 丝袜美腿高跟呻吟高潮一区| 国产精品大片免费观看| 九九综合九九| 蜜臀va亚洲va欧美va天堂| 亚洲黑丝一区二区| 久久午夜精品一区二区| 精品国产午夜肉伦伦影院 | 国产欧美在线| 国产一区久久| 欧美国产不卡| 99视频一区| 神马午夜在线视频| 欧美激情视频一区二区三区免费| 国产精品成久久久久| 日韩极品在线观看| 美女尤物久久精品| 亚洲性视频h| 青青青国产精品| 国产亚洲欧洲| 韩国精品主播一区二区在线观看 | 久久永久免费| 国产免费成人| 久久都是精品| 亚洲精品一二三区区别| 国产一卡不卡| 中文字幕亚洲影视| 蜜臀av一区二区在线免费观看| 91视频一区| 欧美精品三级在线| 日韩欧美精品一区二区综合视频| 欧美日韩视频| 天堂网av成人| 日韩欧美字幕| 久久久久久久久久久9不雅视频| 青青草91视频| 国产精品久久久久久久久免费高清 | 91成人在线网站| 亚洲专区一区| 日韩视频免费| 在线亚洲自拍| 亚洲免费毛片| 国产精品宾馆| 国精品产品一区| 精品国模一区二区三区| 久久精品欧洲| 久久97久久97精品免视看秋霞| 精品国产成人| 亚洲第一精品影视| 国产亚洲毛片| 高清久久精品| 欧美日韩国产一区精品一区| 黄色日韩精品| 亚洲涩涩av| 久久久久久色 | 亚洲精品伊人| 国产精品激情| 久久影院资源站| 久久男人天堂| 蜜桃久久av| 精品国产一区二区三区性色av| 伊人久久大香线蕉av不卡| 国产精品日本欧美一区二区三区| 免费高清在线一区| 国产精品扒开腿做爽爽爽软件| 日韩国产一区| **爰片久久毛片| 中文字幕亚洲影视| 欧美在线日韩| 欧美日韩国产探花| 九九九精品视频| 自拍日韩欧美| 亚洲一区二区免费看| 综合亚洲视频| 国产成人久久| 日韩在线一二三区| 日韩不卡免费高清视频| 欧美自拍一区| 午夜免费一区| 精品国产黄a∨片高清在线| 好看不卡的中文字幕| 国产精品久久久久毛片大屁完整版| 一区二区小说| 欧美国产美女| 欧美一区二区三区久久| 伊人影院久久| 色爱综合网欧美| 国产精品毛片久久久| 国产精品久久亚洲不卡| 韩日一区二区三区| 免费精品国产| 麻豆精品蜜桃视频网站| 亚洲一区二区三区高清| 最新中文字幕在线播放 | 中日韩男男gay无套| 国产999精品在线观看| 国产乱子精品一区二区在线观看 | 亚洲欧美网站在线观看| 久久精品成人| 成人精品天堂一区二区三区| 久久av网站| 国产精品久久| 欧美日本不卡| 国产欧美日韩免费观看| 国产欧美日韩一区二区三区四区 | 日本不卡免费高清视频在线| 久久久国产精品网站| 久久香蕉精品香蕉| se01亚洲视频| 精品一区毛片| 伊人久久成人| 日本一区免费网站| 日韩一区二区三区在线看| 久久精品xxxxx| 国产精品chinese| 久久久久97| 欧美日韩一区二区综合| 亚洲专区欧美专区| 日韩三级视频| 久久av日韩| 三上悠亚国产精品一区二区三区| 国产综合色产| 中文欧美日韩| 国产精品高潮呻吟久久久久| 天堂а√在线最新版中文在线| av资源亚洲| 中文字幕日韩欧美精品高清在线| 日韩美女国产精品| 高清不卡亚洲| 巨乳诱惑日韩免费av| 97精品资源在线观看| 色88888久久久久久影院| 亚洲精品少妇| 日韩电影二区| 视频一区中文字幕| 亚洲综合福利| 热三久草你在线| 日韩精品一级| 成人在线网站| 热久久久久久| 国产亚洲永久域名| 久久精品国产99国产| 91超碰国产精品| 福利视频一区| 国产精品九九| 亚洲va久久久噜噜噜久久| 亚洲www啪成人一区二区| 水野朝阳av一区二区三区| 国产一区2区| 亚洲精品国产日韩| 国产在线一区不卡| 日韩不卡在线观看日韩不卡视频| av不卡免费看| 精品国产三区在线| 日韩一区精品视频| 久久精品国产福利| 在线看片不卡| 捆绑调教美女网站视频一区| 久久国产日本精品| 国产精品v日韩精品v欧美精品网站| 日韩午夜黄色| 日韩精品诱惑一区?区三区| 国产精品久久久久久久久久白浆| 六月婷婷一区| 黄色网一区二区| 免费在线亚洲欧美| 久久精品99国产精品| 天堂网在线观看国产精品| 欧美好骚综合网| 精品精品久久| 久久精品凹凸全集|