
Java Currency Formatter is a short HackerRank exercise about NumberFormat and Locale. The logic is almost nothing: read a number and print it four ways. What it really tests is whether you know that Java can format money for you, with the right symbol, separators and decimal mark for each country, so you never have to glue "$" and commas together by hand.
It is worth doing properly because real projects run into this all the time. Invoices, e-commerce carts and banking screens all show amounts to users in different regions. This problem also has one well-known catch for Indian users, and the output you see can change with the JDK version, which I cover below.
Problem
You are given an amount of money as a double. Using NumberFormat.getCurrencyInstance, format that amount in the currency style of the United States, India, China and France, and print four lines in this order: US: , India: , China: and France: , each followed by the formatted value.
Java has ready-made Locale constants for the US, China and France, but not for India. You have to build the Indian locale yourself with English as the language.
Input: one double, the payment.
Output: four lines, one per country, in the order above.
Constraints: 0 ≤ payment ≤ 109.
Input:
12324.134
Expected output (as shown on HackerRank):
US: $12,324.13
India: Rs.12,324.13
China: ¥12,324.13
France: 12 324,13 €
Approach
- Read the double with a
Scanner. - Get one currency formatter per country with
NumberFormat.getCurrencyInstance(locale). For the US, China and France useLocale.US,Locale.CHINAandLocale.FRANCE. - For India, create the locale from a language code and a country code:
new Locale("en", "IN"). "en" is English and "IN" is India. On JDK 19 and later the constructor is deprecated, andLocale.of("en", "IN")does the same job. - Call
format(payment)on each formatter and print with the right prefix.
The formatter takes care of three things for you: the currency symbol and where it goes (before the number in the US, after it in France), the grouping separator (comma, or a space in France), and the decimal mark (dot, or comma in France). It also rounds to two decimal places using half-even rounding, which is why 12324.134 becomes 12,324.13.
Dry run for 12324.134: the US formatter rounds to 12324.13, adds a comma every three digits and puts "$" in front, giving $12,324.13. The French formatter uses a space for grouping, a comma for decimals and puts "€" at the end, giving 12 324,13 €.
Solution in Java
import java.text.NumberFormat;
import java.util.Locale;
import java.util.Scanner;
public class Solution {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
double payment = scanner.nextDouble();
scanner.close();
// India has no ready-made constant like Locale.US, so build it:
// language "en" (English), country "IN" (India)
Locale india = new Locale("en", "IN");
NumberFormat us = NumberFormat.getCurrencyInstance(Locale.US);
NumberFormat indian = NumberFormat.getCurrencyInstance(india);
NumberFormat china = NumberFormat.getCurrencyInstance(Locale.CHINA);
NumberFormat france = NumberFormat.getCurrencyInstance(Locale.FRANCE);
System.out.println("US: " + us.format(payment));
System.out.println("India: " + indian.format(payment));
System.out.println("China: " + china.format(payment));
System.out.println("France: " + france.format(payment));
}
}
This is the same idea as the old code on this page, which was correct. I only renamed the variables so each one says what it holds.
About the JDK version. I ran this on OpenJDK 21. Since JDK 9, Java takes its locale data from the Unicode CLDR project by default, and that data has changed over the years. So the symbols you see depend on your JDK, even though the code is the same:
- India prints
₹12,324.13on JDK 21, while older JDKs (like JDK 8) printRs.12,324.13, which is what the HackerRank sample shows. - China prints the normal-width yen sign
¥on JDK 21 instead of the full-width¥in the sample. - France on JDK 21 uses a narrow no-break space (U+202F) between digit groups and a no-break space (U+00A0) before €. They look like ordinary spaces but they are different characters, so a byte-by-byte comparison will treat them as different.
If your local output does not match the sample character for character, this is almost always the reason, not your code. Also make sure your terminal uses UTF-8, otherwise ₹ and € show up as question marks.
One more detail: Java's DecimalFormat only uses one grouping size, so even with the Indian locale you get 1,000,000,000.00 and not the lakh-crore style 1,00,00,00,000.00. If you need proper Indian grouping in a real app, use ICU4J or format it yourself.
Output
Output for the sample on OpenJDK 21:
US: $12,324.13
India: ₹12,324.13
China: ¥12,324.13
France: 12 324,13 €
Other values I tried on the same JDK: 0 prints $0.00, ₹0.00, ¥0.00 and 0,00 €. The upper limit 1000000000 prints $1,000,000,000.00 for the US and ₹1,000,000,000.00 for India (western grouping, as explained above). And 1234567.895 prints $1,234,567.90.
Complexity
Time: O(d) per format call, where d is the number of digits, so effectively constant here.
Space: O(1) apart from the four small formatter objects and output strings.
Common mistakes
- Writing
new Locale("IN"). That sets only a language, and Java reads "in" as the old code for Indonesian, so on JDK 21 you get¤12.324,13with a generic currency sign and no country. Always pass the country as the second argument, and use "en" as the problem asks. - Building the string by hand, like
"$" + payment. You lose rounding, grouping and the correct symbol position. - Using
NumberFormat.getInstance()instead ofgetCurrencyInstance(). That formats the number but adds no currency symbol. - Comparing output that "looks" right with the sample and assuming your code is wrong. Check the JDK version and the space characters first.
Related on the site: Java Output Formatting and Java BigDecimal.
Tip: try to solve the problem yourself before reading the solution. Use the code as a reference to check your approach, and make sure you understand why it works.
More HackerRank solutions All coding problems MCQ practice
See everything in one place: Coding Problems and Solutions
Comments
Post a Comment