NumberFormat là lớp cơ sở trừu tượng (abstract) trong package java.text dùng để định dạng (format) và phân tích (parse) số cho các locale khác nhau. Nó xử lý tự động: dấu phân cách hàng nghìn, dấu thập phân, ký hiệu tiền tệ, phần trăm...
Các factory method quan trọng
| Phương thức static | Trả về | Mô tả |
getInstance() | NumberFormat | Định dạng số chung (mặc định locale hệ thống). |
getInstance(Locale) | NumberFormat | Định dạng số cho locale cụ thể. |
getNumberInstance() | NumberFormat | Tương tự getInstance. |
getIntegerInstance() | NumberFormat | Định dạng số nguyên (không phần thập phân). |
getCurrencyInstance() | NumberFormat | Định dạng tiền tệ (có ký hiệu $, €, ¥, ₫...). |
getPercentInstance() | NumberFormat | Định dạng phần trăm (nhân 100 + %). |
getCompactNumberInstance() | NumberFormat | Định dạng số gọn (1.2K, 3.5M - Java 12+). |
Các phương thức instance phổ biến
| Modifier & Type | Phương thức & Mô tả |
String |
format(double number) - Định dạng double thành String. |
String |
format(long number) - Định dạng long thành String. |
StringBuffer |
format(double number, StringBuffer toAppendTo, FieldPosition pos) - Định dạng append vào StringBuffer. |
StringBuffer |
format(long number, StringBuffer toAppendTo, FieldPosition pos) - Tương tự cho long. |
Number |
parse(String source) - Parse chuỗi thành Number (ném ParseException). |
Number |
parse(String source, ParsePosition pos) - Parse từ vị trí pos. |
void |
setMinimumFractionDigits(int) - Số chữ số thập phân tối thiểu. |
void |
setMaximumFractionDigits(int) - Số chữ số thập phân tối đa. |
void |
setGroupingUsed(boolean) - Bật/tắt dấu phân cách nhóm (1,000 vs 1000). |
void |
setCurrency(Currency) - Đặt đơn vị tiền tệ. |
Ví dụ 1: Định dạng tiền tệ (Locale FRANCE)
import java.text.NumberFormat;
import java.util.Locale;
public class Demo {
public static void main(String[] args) {
NumberFormat n = NumberFormat.getCurrencyInstance(Locale.FRANCE);
double points = 2.15;
double totalPoints = points * 1000;
System.out.println(n.format(points)); // 2,15 €
System.out.println(n.format(totalPoints)); // 2 150,00 €
}
}
Kết quả
2,15 €
2 150,00 €
Ví dụ 2: So sánh locale Việt Nam vs Mỹ
import java.text.NumberFormat;
import java.util.Locale;
public class Demo {
public static void main(String[] args) {
Locale vnLocale = new Locale("vi", "VN");
Locale usLocale = Locale.US;
NumberFormat vnFormat = NumberFormat.getInstance(vnLocale);
NumberFormat usFormat = NumberFormat.getInstance(usLocale);
double value = 1234567.89;
System.out.println("Việt Nam: " + vnFormat.format(value)); // 1.234.567,89
System.out.println("Mỹ: " + usFormat.format(value)); // 1,234,567.89
// Tiền tệ
NumberFormat vnCurrency = NumberFormat.getCurrencyInstance(vnLocale);
NumberFormat usCurrency = NumberFormat.getCurrencyInstance(usLocale);
System.out.println("VNĐ: " + vnCurrency.format(value)); // 1.234.567 ₫
System.out.println("USD: " + usCurrency.format(value)); // $1,234,567.89
}
}
Ví dụ 3: Tùy chỉnh định dạng
import java.text.NumberFormat;
import java.util.Locale;
public class Demo {
public static void main(String[] args) {
NumberFormat nf = NumberFormat.getInstance(Locale.US);
// Cố định 2 chữ số thập phân
nf.setMinimumFractionDigits(2);
nf.setMaximumFractionDigits(2);
System.out.println(nf.format(100.5)); // 100.50
System.out.println(nf.format(100)); // 100.00
// Tắt grouping
nf.setGroupingUsed(false);
System.out.println(nf.format(1000000)); // 1000000.00
// Parse ngược
try {
Number num = nf.parse("1,234.56");
System.out.println("Parsed: " + num.doubleValue()); // 1234.56
} catch (Exception e) {
e.printStackTrace();
}
}
}
Ví dụ 4: Định dạng gọn (Compact Number Format - Java 12+)
import java.text.NumberFormat;
import java.util.Locale;
public class CompactDemo {
public static void main(String[] args) {
NumberFormat compactShort = NumberFormat.getCompactNumberInstance(
Locale.US, NumberFormat.Style.SHORT);
NumberFormat compactLong = NumberFormat.getCompactNumberInstance(
Locale.US, NumberFormat.Style.LONG);
long[] values = {999, 1000, 1500, 1_000_000, 2_500_000_000L};
for (long v : values) {
System.out.printf("%12d -> Short: %-6s Long: %s%n",
v, compactShort.format(v), compactLong.format(v));
}
}
}
Kết quả (Java 12+)
999 -> Short: 999 Long: 999
1000 -> Short: 1K Long: 1 thousand
1500 -> Short: 1.5K Long: 1.5 thousand
1000000 -> Short: 1M Long: 1 million
2500000000 -> Short: 2.5B Long: 2.5 billion
Lưu ý quan trọng
NumberFormat không thread-safe. Mỗi luồng nên có instance riêng hoặc synchronized.
- Dùng
Locale phù hợp để hiển thị đúng chuẩn địa phương (VN: dấu chấm phân cách nghìn, dấu phẩy thập phân).
- Parse trả về
Number (có thể là Long, Double, BigDecimal...). Dùng .doubleValue(), .longValue() để lấy giá trị.
- Từ Java 12,
CompactNumberFormat rất hay cho UI dashboard, báo cáo.