জাভাতে অর্থের জন্য আপনার কোন ডেটা টাইপ ব্যবহার করা উচিত?
জাভাতে অর্থের জন্য আপনার কোন ডেটা টাইপ ব্যবহার করা উচিত?
উত্তর:
জাভাতে Currency
ক্লাস রয়েছে যা আইএসও 4217 মুদ্রা কোড উপস্থাপন করে।
BigDecimal
দশমিক মানগুলি উপস্থাপনের জন্য সেরা ধরণ।
জোদা মানি অর্থ উপস্থাপনের জন্য একটি লাইব্রেরি সরবরাহ করেছে।
আপনি অর্থ এবং মুদ্রার এপিআই (জেএসআর 354) ব্যবহার করতে পারেন । আপনি যদি আপনার প্রকল্পে যথাযথ নির্ভরতা যুক্ত করেন তবে আপনি এই API এ ব্যবহার করতে পারেন।
জাভা 8 এর জন্য, আপনার উপর নির্ভরতা হিসাবে নিম্নলিখিত রেফারেন্স প্রয়োগটি যুক্ত করুন pom.xml
:
<dependency>
<groupId>org.javamoney</groupId>
<artifactId>moneta</artifactId>
<version>1.0</version>
</dependency>
এই নির্ভরতা ট্রানজিটিভভাবে নির্ভরতা javax.money:money-api
হিসাবে যুক্ত করবে ।
তারপরে আপনি এপিআই ব্যবহার করতে পারেন:
package com.example.money;
import static org.junit.Assert.assertThat;
import static org.hamcrest.CoreMatchers.is;
import java.util.Locale;
import javax.money.Monetary;
import javax.money.MonetaryAmount;
import javax.money.MonetaryRounding;
import javax.money.format.MonetaryAmountFormat;
import javax.money.format.MonetaryFormats;
import org.junit.Test;
public class MoneyTest {
@Test
public void testMoneyApi() {
MonetaryAmount eurAmount1 = Monetary.getDefaultAmountFactory().setNumber(1.1111).setCurrency("EUR").create();
MonetaryAmount eurAmount2 = Monetary.getDefaultAmountFactory().setNumber(1.1141).setCurrency("EUR").create();
MonetaryAmount eurAmount3 = eurAmount1.add(eurAmount2);
assertThat(eurAmount3.toString(), is("EUR 2.2252"));
MonetaryRounding defaultRounding = Monetary.getDefaultRounding();
MonetaryAmount eurAmount4 = eurAmount3.with(defaultRounding);
assertThat(eurAmount4.toString(), is("EUR 2.23"));
MonetaryAmountFormat germanFormat = MonetaryFormats.getAmountFormat(Locale.GERMAN);
assertThat(germanFormat.format(eurAmount4), is("EUR 2,23") );
}
}
একটি অবিচ্ছেদ্য প্রকার যা সম্ভব ক্ষুদ্রতম মানকে উপস্থাপন করে। অন্য কথায় আপনার প্রোগ্রামটি ডলার / ইউরোতে নয় সেন্টে ভাবা উচিত।
এটি আপনাকে জিআই এর ডলার / ইউরোতে আবার অনুবাদ করতে বাধা দেওয়া উচিত নয়।
বিগডিসিমাল ব্যবহার করা যেতে পারে, কেন ফ্লোট বা ডাবল ব্যবহার করবেন না তার ভাল ব্যাখ্যা এখানে দেখা যাবে: মুদ্রার প্রতিনিধিত্ব করতে ডাবল বা ফ্লোট ব্যবহার করবেন না কেন?
জেএসআর 354: অর্থ এবং মুদ্রার এপিআই
জেএসআর 354 অর্থ এবং মুদ্রার সাথে ব্যাপক গণনা উপস্থাপন, পরিবহন এবং সম্পাদনের জন্য একটি এপিআই সরবরাহ করে। আপনি এই লিঙ্ক থেকে এটি ডাউনলোড করতে পারেন:
জেএসআর 354: অর্থ এবং মুদ্রার এপিআই ডাউনলোড করুন
স্পেসিফিকেশন নিম্নলিখিত জিনিস নিয়ে গঠিত:
- হ্যান্ডলিংয়ের জন্য একটি API যেমন আর্থিক পরিমাণ এবং মুদ্রা
- বিনিময়যোগ্য প্রয়োগগুলি সমর্থন করার জন্য API গুলি
- বাস্তবায়ন ক্লাসগুলির উদাহরণ তৈরির কারখানাগুলি
- গণনা, রূপান্তর এবং আর্থিক পরিমাণের বিন্যাসকরণের জন্য কার্যকারিতা
- মানি এবং মুদ্রার সাথে কাজ করার জন্য জাভা এপিআই, যা জাভা 9 এ অন্তর্ভুক্ত করার পরিকল্পনা করা হয়েছে।
- সমস্ত স্পেসিফিকেশন ক্লাস এবং ইন্টারফেস javax.money। * প্যাকেজে অবস্থিত।
জেএসআর 354 এর নমুনা উদাহরণ: অর্থ এবং মুদ্রার এপিআই:
মুদ্রাআমাউন্ট তৈরি করার এবং কনসোলে এটি মুদ্রণের উদাহরণটি দেখতে এরকম দেখাচ্ছে:
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));
রেফারেন্স বাস্তবায়ন এপিআই ব্যবহার করার সময়, প্রয়োজনীয় কোডটি অনেক সহজ:
MonetaryAmount monetaryAmount = Money.of(12345.67, "EUR");
MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(Locale.getDefault());
System.out.println(format.format(monetaryAmount));
এপিআই মনিটারিঅ্যামাউন্টস সহ গণনাগুলি সমর্থন করে:
MonetaryAmount monetaryAmount = Money.of(12345.67, "EUR");
MonetaryAmount otherMonetaryAmount = monetaryAmount.divide(2).add(Money.of(5, "EUR"));
কারেন্সিউইনিট এবং মুদ্রাঅ্যামাউন্ট
// getting CurrencyUnits by locale
CurrencyUnit yen = MonetaryCurrencies.getCurrency(Locale.JAPAN);
CurrencyUnit canadianDollar = MonetaryCurrencies.getCurrency(Locale.CANADA);
মানিটারাউন্টে বিভিন্ন পদ্ধতি রয়েছে যা নির্ধারিত মুদ্রা, সংখ্যার পরিমাণ, তার যথার্থতা এবং আরও অনেক কিছু অ্যাক্সেসের অনুমতি দেয়:
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
মানিএমাউন্টগুলির সংগ্রহের সাথে কাজ করার সময়, ফিল্টারিং, বাছাই এবং গোষ্ঠীকরণের জন্য কয়েকটি দুর্দান্ত ইউটিলিটি পদ্ধতি উপলব্ধ।
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"));
কাস্টম মানিঅ্যামাউন্ট ক্রিয়াকলাপ
// 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
সম্পদ:
জেএসআর 354 এর সাহায্যে জাভাতে অর্থ এবং মুদ্রা পরিচালনা করা
জাভা 9 অর্থ এবং মুদ্রার এপিআই (জেএসআর 354) সন্ধান করছেন
আরও দেখুন: জেএসআর 354 - মুদ্রা এবং অর্থ
আপনার আর্থিক মূল্যবোধ উপস্থাপনের জন্য আপনার বিগডিসিমাল ব্যবহার করা উচিত t এটি আপনাকে বিভিন্ন ধরণের রাউন্ডিং মোডগুলি ব্যবহার করতে দেয় এবং আর্থিক অ্যাপ্লিকেশনগুলিতে প্রায়শই রাউন্ডিং মোড একটি কঠোর প্রয়োজন যা এমনকি আইন দ্বারা বাধ্যতামূলকও হতে পারে।
পারফরম্যান্সের দিক থেকে বিগডেসিমেলের বিপরীতে মনতা (জাভা মুদ্রা জেএসআর 354 বাস্তবায়ন) তুলনা করার জন্য আমি একটি মাইক্রোব্যাঙ্কমার্ক (জেএমএইচ) করেছি।
আশ্চর্যের বিষয়, বিগডিসিমাল পারফরম্যান্স মনিতার চেয়ে ভাল বলে মনে হচ্ছে। আমি নীচে নীচে কনফিগার ব্যবহার করেছি:
org.javamoney.moneta.Money.defaults.precision = 19 org.javamoney.moneta.Money.defaults.roundingMode = HALF_UP
package com.despegar.bookedia.money;
import org.javamoney.moneta.FastMoney;
import org.javamoney.moneta.Money;
import org.openjdk.jmh.annotations.*;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.concurrent.TimeUnit;
@Measurement(batchSize = 5000, iterations = 10, time = 2, timeUnit = TimeUnit.SECONDS)
@Warmup(iterations = 2)
@Threads(value = 1)
@Fork(value = 1)
@State(Scope.Benchmark)
@BenchmarkMode(Mode.Throughput)
public class BigDecimalBenchmark {
private static final Money MONEY_BASE = Money.of(1234567.3444, "EUR");
private static final Money MONEY_SUBSTRACT = Money.of(232323, "EUR");
private static final FastMoney FAST_MONEY_SUBSTRACT = FastMoney.of(232323, "EUR");
private static final FastMoney FAST_MONEY_BASE = FastMoney.of(1234567.3444, "EUR");
MathContext mc = new MathContext(10, RoundingMode.HALF_UP);
@Benchmark
public void bigdecimal_string() {
new BigDecimal("1234567.3444").subtract(new BigDecimal("232323")).multiply(new BigDecimal("3.4"), mc).divide(new BigDecimal("5.456"), mc);
}
@Benchmark
public void bigdecimal_valueOf() {
BigDecimal.valueOf(12345673444L, 4).subtract(BigDecimal.valueOf(232323L)).multiply(BigDecimal.valueOf(34, 1), mc).divide(BigDecimal.valueOf(5456, 3), mc);
}
@Benchmark
public void fastmoney() {
FastMoney.of(1234567.3444, "EUR").subtract(FastMoney.of(232323, "EUR")).multiply(3.4).divide(5.456);
}
@Benchmark
public void money() {
Money.of(1234567.3444, "EUR").subtract(Money.of(232323, "EUR")).multiply(3.4).divide(5.456);
}
@Benchmark
public void money_static(){
MONEY_BASE.subtract(MONEY_SUBSTRACT).multiply(3.4).divide(5.456);
}
@Benchmark
public void fastmoney_static() {
FAST_MONEY_BASE.subtract(FAST_MONEY_SUBSTRACT).multiply(3.4).divide(5.456);
}
}
ফলাফল
Benchmark Mode Cnt Score Error Units
BigDecimalBenchmark.bigdecimal_string thrpt 10 479.465 ± 26.821 ops/s
BigDecimalBenchmark.bigdecimal_valueOf thrpt 10 1066.754 ± 40.997 ops/s
BigDecimalBenchmark.fastmoney thrpt 10 83.917 ± 4.612 ops/s
BigDecimalBenchmark.fastmoney_static thrpt 10 504.676 ± 21.642 ops/s
BigDecimalBenchmark.money thrpt 10 59.897 ± 3.061 ops/s
BigDecimalBenchmark.money_static thrpt 10 184.767 ± 7.017 ops/s
যদি আমি কিছু মিস করছি তবে দয়া করে আমাকে সংশোধন করতে দ্বিধা বোধ করবেন
সাধারণ ক্ষেত্রে (এক মুদ্রার জন্য) এটি যথেষ্ট Integer
/ Long
। সেন্টগুলিতে অর্থ (...) বা শততম / হাজারতম সেন্টে রাখুন (নির্দিষ্ট বিভাজকের সাথে আপনার যে কোনও নির্ভুলতা প্রয়োজন)
বিগডিসিমাল মুদ্রার জন্য ব্যবহারের জন্য সেরা ডেটা টাইপ।
মুদ্রার জন্য প্রচুর পরিমাণে ধারক রয়েছে তবে তারা সবাই বিগডিসিমালকে অন্তর্নিহিত ডেটা ধরণ হিসাবে ব্যবহার করে। আপনি বিগডিসিমেলের সাথে ভুল হবেন না, সম্ভবত বিগডিসিমাল ব্যবহার করুন ND_
আমি টিনি টাইপগুলি ব্যবহার করতে পছন্দ করি যা পূর্ববর্তী উত্তরগুলির পরামর্শ অনুসারে ডাবল, বিগডিসিমাল বা ইন্টি আঁটবে। (যথাযথ সমস্যাগুলি না কাটলে আমি দ্বিগুণ ব্যবহার করব)।
একটি ক্ষুদ্র প্রকার আপনাকে টাইপ সুরক্ষা দেয় যাতে আপনি অন্য ডাবলসের সাথে দ্বিগুণ অর্থ বিভ্রান্ত না করেন।