Heim Java javaLernprogramm Neue Währungs-API in Java 9

Neue Währungs-API in Java 9

Nov 26, 2016 am 10:10 AM
api java

JSR 354 definiert eine neue Java-Währungs-API, deren offizielle Einführung in Java 9 geplant ist. In diesem Artikel werfen wir einen Blick auf die Referenzimplementierung: den aktuellen Fortschritt von JavaMoney.

Genau wie mein vorheriger Artikel über die neue Datums- und Uhrzeit-API von Java 8 demonstriert dieser Artikel hauptsächlich die Verwendung der neuen API durch Code.

Bevor ich anfange, möchte ich einen Absatz verwenden, um den Zweck dieses neuen Satzes von APIs, die durch die Spezifikation definiert werden, kurz zusammenzufassen:

Für viele Anwendungen ist der Geldwert ein Schlüsselmerkmal. aber JDK bietet dafür fast keine Unterstützung. Genau genommen stellt die vorhandene Klasse java.util.Currency nur eine Datenstruktur der aktuellen ISO 4217-Währung dar, verfügt jedoch über keine zugehörigen Werte oder benutzerdefinierten Währungen. JDK verfügt außerdem über keine integrierte Unterstützung für Währungsoperationen und -umrechnungen, geschweige denn über einen Standardtyp, der Währungswerte darstellen kann.

Wenn Sie Maven verwenden, müssen Sie dem Projekt nur die folgende Referenz hinzufügen, um die aktuellen Funktionen der Referenzimplementierung zu erleben:

<dependency>
  <groupId>org.javamoney</groupId>
  <artifactId>moneta</artifactId>
  <version>0.9</version>
</dependency>
Nach dem Login kopieren

Die in der Spezifikation genannten Klassen und Schnittstellen sind unter dem Paket javax.money.*.

Beginnen wir mit den beiden Kernschnittstellen, CurrencyUnit und MonetaryAmount.

CurrencyUnit und MonetaryAmount

CurrencyUnit stellt die Währung dar. Sie ähnelt in gewisser Weise der aktuellen Klasse java.util.Currency, unterstützt jedoch benutzerdefinierte Implementierungen. Aus der Standarddefinition kann java.util.Currency diese Schnittstelle auch implementieren. Instanzen von „CurrencyUnit“ können über die MonetaryCurrencies-Fabrik abgerufen werden:

// 根据货币代码来获取货币单位 CurrencyUnit euro = MonetaryCurrencies.getCurrency("EUR");
    CurrencyUnit usDollar = MonetaryCurrencies.getCurrency("USD"); // 根据国家及地区来获取货币单位
    CurrencyUnit yen = MonetaryCurrencies.getCurrency(Locale.JAPAN); CurrencyUnit
    canadianDollar = MonetaryCurrencies.getCurrency(Locale.CANADA);
Nach dem Login kopieren

MontetaryAmount stellt den spezifischen Betrag einer bestimmten Währung dar. Normalerweise ist es an eine Währungseinheit gebunden.

MontetaryAmount ist wie auch CurrencyUnit eine Schnittstelle, die mehrere Implementierungen unterstützen kann.

Implementierungen von CurrencyUnit und MontetaryAmount müssen unveränderlich, threadsicher und vergleichbar sein.

/ get MonetaryAmount from CurrencyUnit
CurrencyUnit euro = MonetaryCurrencies.getCurrency("EUR");
MonetaryAmount fiveEuro = Money.of(5, euro);
  
// get MonetaryAmount from currency code
MonetaryAmount tenUsDollar = Money.of(10, "USD");
  
// FastMoney is an alternative MonetaryAmount factory that focuses on performance
MonetaryAmount sevenEuro = FastMoney.of(7, euro);
Nach dem Login kopieren

Money und FastMoney sind zwei Implementierungen von MonetaryAmount in der JavaMoney-Bibliothek. Money ist die Standardimplementierung, die BigDecimal zum Speichern von Beträgen verwendet. FastMoney ist eine optionale Implementierung, die zum Speichern von Beträgen den Typ „Long“ verwendet. Der Dokumentation zufolge sind Vorgänge auf FastMoney etwa 10 bis 15 Mal schneller als auf Money. Allerdings sind Betragsgröße und Präzision von FastMoney auf den Long-Typ beschränkt.

Beachten Sie, dass Money und FastMoney hier spezifische Implementierungsklassen sind (sie befinden sich unter dem Paket org.javamoney.moneta.*, nicht unter javax.money.*). Wenn Sie keinen bestimmten Typ angeben möchten, können Sie MonetaryAmountFactory verwenden, um eine Instanz von MonetaryAmount zu generieren:

MonetaryAmount specAmount = MonetaryAmounts.getDefaultAmountFactory()
                .setNumber(123.45) .setCurrency("USD") .create();
Nach dem Login kopieren

Diese beiden MontetaryAmount-Instanzen gelten nur dann und nur dann als gleich, wenn die Implementierungsklasse Währung ist Einheit und Wert sind alle gleich.

MonetaryAmount oneEuro = Money.of(1, MonetaryCurrencies.getCurrency("EUR"));
boolean isEqual = oneEuro.equals(Money.of(1, "EUR")); // true
boolean isEqualFast = oneEuro.equals(FastMoney.of(1, "EUR")); // false
Nach dem Login kopieren

MonetaryAmount enthält eine Fülle von Methoden, mit denen bestimmte Währungen, Beträge, Genauigkeiten usw. ermittelt werden können:

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;
Nach dem Login kopieren

Die Verwendung von MonetaryAmount

finden Sie unter Arithmetische Operationen auf 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 NumberValue
MonetaryAmount minusTwoEuro = fiveEuro.subtract(sevenEuro); // "EUR -2"
  
// some useful utility methods
boolean greaterThan = sevenEuro.isGreaterThan(fiveEuro); // true
boolean positive = sevenEuro.isPositive(); // true
boolean 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/USD
fiveEuro.add(tenUsDollar);
Nach dem Login kopieren

Rundungsoperationen sind ein sehr wichtiger Teil der Betragsumrechnung. MonetaryAmount kann mit dem Rundungsoperator gerundet werden:

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
Nach dem Login kopieren

Hier werden 12,3456 US-Dollar gemäß den Standardrundungsregeln der aktuellen Währung umgerechnet.

Beim Betrieb der MonetaryAmount-Sammlung gibt es viele praktische Tools und Methoden, die zum Filtern, Sortieren und Gruppieren verwendet werden können. Diese Methoden können auch mit der Streams-API von Java 8 verwendet werden.

Sehen Sie sich die folgende Sammlung an:

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"));
Nach dem Login kopieren

Wir können den Betrag nach Währungseinheit filtern:

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());
Nach dem Login kopieren

Wir können auch größere Beträge herausfiltern als oder kleiner als ein bestimmter Schwellenwert Der Betrag:

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());
Nach dem Login kopieren

Die Sortierung ist ebenfalls ähnlich:

// 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());
Nach dem Login kopieren

Es gibt auch Gruppierungsoperationen:

// 按货币单位进行分组
// {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 USD
MonetarySummaryStatistics 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
Nach dem Login kopieren

MonetaryFunctions Bietet auch eine Reduktionsfunktion, die verwendet werden kann, um den Maximalwert, den Minimalwert und die Summe zu erhalten:

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()); //
Nach dem Login kopieren

Benutzerdefinierte MonetaryAmount-Operation

MonetaryAmount bietet außerdem einen sehr benutzerfreundlichen Erweiterungspunkt namens MonetaryOperator . MonetaryOperator ist eine funktionale Schnittstelle, die einen MonetaryAmount-Eingabeparameter empfängt und ein neues MonetaryAmount-Objekt zurückgibt.

// 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
Nach dem Login kopieren

Standard-API-Funktionen werden über die MonetaryOperator-Schnittstelle implementiert. Beispielsweise wird die oben beschriebene Rundungsoperation in Form der MonetaryOperator-Schnittstelle bereitgestellt.

Wechselkurs

Der Wechselkurs kann über ExchangeRateProvider abgerufen werden. JavaMoney wird mit mehreren verschiedenen ExchangeRateProvider-Implementierungen geliefert. Die beiden wichtigsten sind ECBCurrentRateProvider und IMFRateProvider.

ECBCurrentRateProvider fragt die Daten der Europäischen Zentralbank (EZB) ab und IMFRateProvider fragt den Wechselkurs des Internationalen Währungsfonds (IWF) ab.

// 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");
Nach dem Login kopieren

Wenn ExchangeRateProvider nicht angegeben ist, wird CompoundRateProvider zurückgegeben. Der CompoundRateProvider delegiert Wechselkursumrechnungsanfragen an eine Kette von ExchangeRateProvider und gibt Daten vom ersten Anbieter zurück, der genaue Ergebnisse zurückgibt.

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

Währungsumrechnung

Die Umrechnung zwischen verschiedenen Währungen kann über die von ExchangeRateProvider zurückgegebenen „CurrencyConversions“ durchgeführt werden.

// get the CurrencyConversion from the default provider chain
CurrencyConversion dollarConversion = MonetaryConversions.getConversion("USD");
  
// get the CurrencyConversion from a specific provider
CurrencyConversion 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)
Nach dem Login kopieren

Bitte beachten Sie, dass CurrencyConversion auch die MonetaryOperator-Schnittstelle implementiert. Wie andere Operationen kann es auch über die Methode MonetaryAmount.with() aufgerufen werden.

Formatieren und Parsen

  MonetaryAmount可以通过MonetaryAmountFormat来与字符串进行解析/格式化。

// formatting by locale specific formats
MonetaryAmountFormat 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 strings
MonetaryAmount parsed = germanFormat.parse("12,4 USD");
Nach dem Login kopieren

可以通过AmountFormatQueryBuilder来生成自定义的格式。

// Creating a custom MonetaryAmountFormat
MonetaryAmountFormat 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);
Nach dem Login kopieren

注意,这里的¤符号在模式串中是作为货币的占位符。

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Wie man alles in Myrise freischaltet
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Quadratwurzel in Java Quadratwurzel in Java Aug 30, 2024 pm 04:26 PM

Leitfaden zur Quadratwurzel in Java. Hier diskutieren wir anhand eines Beispiels und seiner Code-Implementierung, wie Quadratwurzel in Java funktioniert.

Perfekte Zahl in Java Perfekte Zahl in Java Aug 30, 2024 pm 04:28 PM

Leitfaden zur perfekten Zahl in Java. Hier besprechen wir die Definition, Wie prüft man die perfekte Zahl in Java?, Beispiele mit Code-Implementierung.

Zufallszahlengenerator in Java Zufallszahlengenerator in Java Aug 30, 2024 pm 04:27 PM

Leitfaden zum Zufallszahlengenerator in Java. Hier besprechen wir Funktionen in Java anhand von Beispielen und zwei verschiedene Generatoren anhand ihrer Beispiele.

Weka in Java Weka in Java Aug 30, 2024 pm 04:28 PM

Leitfaden für Weka in Java. Hier besprechen wir die Einführung, die Verwendung von Weka Java, die Art der Plattform und die Vorteile anhand von Beispielen.

Smith-Nummer in Java Smith-Nummer in Java Aug 30, 2024 pm 04:28 PM

Leitfaden zur Smith-Zahl in Java. Hier besprechen wir die Definition: Wie überprüft man die Smith-Nummer in Java? Beispiel mit Code-Implementierung.

Fragen zum Java Spring-Interview Fragen zum Java Spring-Interview Aug 30, 2024 pm 04:29 PM

In diesem Artikel haben wir die am häufigsten gestellten Fragen zu Java Spring-Interviews mit ihren detaillierten Antworten zusammengestellt. Damit Sie das Interview knacken können.

Brechen oder aus Java 8 Stream foreach zurückkehren? Brechen oder aus Java 8 Stream foreach zurückkehren? Feb 07, 2025 pm 12:09 PM

Java 8 führt die Stream -API ein und bietet eine leistungsstarke und ausdrucksstarke Möglichkeit, Datensammlungen zu verarbeiten. Eine häufige Frage bei der Verwendung von Stream lautet jedoch: Wie kann man von einem Foreach -Betrieb brechen oder zurückkehren? Herkömmliche Schleifen ermöglichen eine frühzeitige Unterbrechung oder Rückkehr, aber die Stream's foreach -Methode unterstützt diese Methode nicht direkt. In diesem Artikel werden die Gründe erläutert und alternative Methoden zur Implementierung vorzeitiger Beendigung in Strahlverarbeitungssystemen erforscht. Weitere Lektüre: Java Stream API -Verbesserungen Stream foreach verstehen Die Foreach -Methode ist ein Terminalbetrieb, der einen Vorgang für jedes Element im Stream ausführt. Seine Designabsicht ist

Zeitstempel für Datum in Java Zeitstempel für Datum in Java Aug 30, 2024 pm 04:28 PM

Anleitung zum TimeStamp to Date in Java. Hier diskutieren wir auch die Einführung und wie man Zeitstempel in Java in ein Datum konvertiert, zusammen mit Beispielen.

See all articles