NumberFormat e printf
Formate números para exibição usando NumberFormat, DecimalFormat e padrões de printf.
NumberFormat e printf é uma aula grátis de Java Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Java Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Java Academy inclui 4 aulas no total.
NumberFormat e printf
Java oferece APIs avançadas de formatação numérica: NumberFormat para moeda e porcentagem de acordo com a localidade, DecimalFormat para padrões personalizados e printf/String.format para formatação no estilo C.
Noções básicas de String.format
String.format() usa especificadores de formato para construir strings. Especificadores comuns: %d (inteiro), %f (ponto flutuante), %s (string), %n (nova linha).
String name = "Alice";
int score = 95;
double avg = 87.567;
String msg = String.format(
"Player: %s | Score: %d | Average: %.2f", name, score, avg);
System.out.println(msg);
// Player: Alice | Score: 95 | Average: 87.57
// printf is equivalent — formats directly to output
System.out.printf("%-10s %5d %8.2f%n", name, score, avg);
// Alice 95 87.57Largura, preenchimento e alinhamento
Os especificadores de formato aceitam sinalizadores de largura e alinhamento: %10d (alinhamento à direita em 10 caracteres), %-10d (alinhamento à esquerda), %010d (preenchimento com zeros).
// Table layout with padding
System.out.printf("%-20s %10s %10s%n", "Product", "Qty", "Price");
System.out.printf("%-20s %10d %10.2f%n", "Java Book", 3, 49.99);
System.out.printf("%-20s %10d %10.2f%n", "USB Hub", 1, 24.95);
System.out.printf("%-20s %10d %10.2f%n", "Mechanical Keyboard", 2, 129.00);
// Zero-padding for order IDs
int orderId = 42;
System.out.printf("Order: ORD-%08d%n", orderId); // Order: ORD-00000042NumberFormat para moedas
NumberFormat.getCurrencyInstance(Locale) formata números como strings monetárias com o símbolo, os separadores e as casas decimais corretos para uma determinada localidade.
import java.text.*;
import java.util.*;
NumberFormat usd = NumberFormat.getCurrencyInstance(Locale.US);
NumberFormat eur = NumberFormat.getCurrencyInstance(Locale.GERMANY);
NumberFormat gbp = NumberFormat.getCurrencyInstance(Locale.UK);
double amount = 1234567.89;
System.out.println(usd.format(amount)); // $1,234,567.89
System.out.println(eur.format(amount)); // 1.234.567,89 EUR
System.out.println(gbp.format(amount)); // GBP1,234,567.89NumberFormat para porcentagens
NumberFormat.getPercentInstance() formata um decimal como uma string de porcentagem. Passe um valor entre 0 e 1.
import java.text.*;
import java.util.*;
NumberFormat pct = NumberFormat.getPercentInstance(Locale.US);
pct.setMaximumFractionDigits(1);
System.out.println(pct.format(0.75)); // 75%
System.out.println(pct.format(0.1234)); // 12.3%
System.out.println(pct.format(1.0)); // 100%
// Conversion rate in e-commerce
double convRate = 3_456.0 / 42_000.0;
System.out.println("Conversion: " + pct.format(convRate)); // 8.2%DecimalFormat com padrões personalizados
DecimalFormat usa uma string de padrão em que # representa um algarismo opcional e 0 representa um algarismo obrigatório.
import java.text.*;
DecimalFormat df1 = new DecimalFormat("#,###.00");
System.out.println(df1.format(1234567.5)); // 1,234,567.50
DecimalFormat df2 = new DecimalFormat("000.0");
System.out.println(df2.format(7.5)); // 007.5
DecimalFormat df3 = new DecimalFormat("0.00E0");
System.out.println(df3.format(0.000123)); // 1.23E-4
// Scientific notation for large values
DecimalFormat sci = new DecimalFormat("0.000E0");
System.out.println(sci.format(123456789)); // 1.235E8Analisando números a partir de strings
NumberFormat também pode analisar strings formatadas de acordo com a localidade e convertê-las novamente em números. Isso é essencial para ler dados inseridos pelos usuários em diferentes localidades.
import java.text.*;
import java.util.*;
NumberFormat nf = NumberFormat.getInstance(Locale.GERMANY);
try {
// German uses comma as decimal separator
Number parsed = nf.parse("1.234,56");
System.out.println(parsed.doubleValue()); // 1234.56
// Parse US currency string
NumberFormat usd = NumberFormat.getCurrencyInstance(Locale.US);
Number amount = usd.parse("$1,234.56");
System.out.println(amount.doubleValue()); // 1234.56
} catch (ParseException e) {
System.out.println("Parse error: " + e.getMessage());
}Strings formatadas (Java 15+)
Java 15+ adiciona String.formatted() como uma alternativa de método de instância a String.format(), útil em encadeamentos de métodos e sequências de stream.
record Product(String name, double price, int stock) {}
var products = List.of(
new Product("Laptop", 999.0, 5),
new Product("Mouse", 29.99, 42),
new Product("Monitor", 349.0, 8)
);
products.stream()
.map(p -> "%-15s $%8.2f [stock: %d]"
.formatted(p.name(), p.price(), p.stock()))
.forEach(System.out::println);
// Laptop $ 999.00 [stock: 5]
// Mouse $ 29.99 [stock: 42]
// Monitor $ 349.00 [stock: 8]Agrupamento de números e localidade
O agrupamento de números (separador de milhares) varia conforme a localidade. Sempre use NumberFormat para a saída exibida aos usuários, em vez de codificar vírgulas diretamente.
import java.text.*;
import java.util.*;
long users = 1_234_567;
for (Locale locale : new Locale[]{Locale.US, Locale.FRANCE, Locale.GERMANY}) {
NumberFormat nf = NumberFormat.getIntegerInstance(locale);
System.out.printf("%-10s: %s%n", locale, nf.format(users));
}
// en_US : 1,234,567
// fr_FR : 1 234 567
// de_DE : 1.234.567Exemplo de geração de fatura
Juntando tudo: geração de uma fatura formatada com moeda e porcentagem corretas e alinhamento adequado da tabela.
import java.text.*;
import java.util.*;
NumberFormat curr = NumberFormat.getCurrencyInstance(Locale.US);
NumberFormat pct = NumberFormat.getPercentInstance();
pct.setMaximumFractionDigits(0);
double subtotal = 1259.97;
double discount = 0.10;
double discountAmt = subtotal * discount;
double taxRate = 0.08;
double taxAmt = (subtotal - discountAmt) * taxRate;
double total = subtotal - discountAmt + taxAmt;
System.out.println("=== INVOICE ===");
System.out.printf("%-20s %15s%n", "Subtotal", curr.format(subtotal));
System.out.printf("%-20s %15s%n", "Discount (" + pct.format(discount) + ")",
"-" + curr.format(discountAmt));
System.out.printf("%-20s %15s%n", "Tax (" + pct.format(taxRate) + ")",
curr.format(taxAmt));
System.out.printf("%-20s %15s%n", "TOTAL", curr.format(total));Armadilhas comuns
Fique atento a estes erros comuns de formatação:
- Usar
String.formatcom um especificador de tipo incorreto (por exemplo,%dpara umdouble) lançaIllegalFormatConversionException - Formatadores específicos de uma localidade produzem saídas diferentes em máquinas diferentes
- As instâncias de NumberFormat não são seguras para uso concorrente — crie uma por fluxo de execução ou use
ThreadLocal
// Wrong specifier
try {
String.format("%d", 3.14); // IllegalFormatConversionException
} catch (java.util.IllegalFormatConversionException e) {
System.out.println("Wrong format specifier!");
}
// Thread-safe pattern using ThreadLocal
ThreadLocal<NumberFormat> localFmt = ThreadLocal
.withInitial(() -> NumberFormat.getCurrencyInstance(Locale.US));
// each thread gets its own NumberFormat instanceVerificação rápida
O que String.format("%08.2f", 3.5) produz?
Recapitulação: NumberFormat e printf
Principais conclusões:
- String.format / printf usam especificadores de formato: %d, %f, %s, %.2f
- Sinalizadores de largura e alinhamento: %10d (direita), %-10d (esquerda), %010d (preenchimento com zeros)
- NumberFormat.getCurrencyInstance() para exibição de moedas de acordo com a localidade
- NumberFormat.getPercentInstance() para saída de porcentagens
- DecimalFormat usa padrões de algarismos com # (opcional) e 0 (obrigatório)
- NumberFormat também pode analisar strings formatadas de acordo com a localidade e convertê-las novamente em números
Perguntas Frequentes
A aula “NumberFormat e printf” é grátis?
Sim — o texto completo de “NumberFormat e printf” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Java Academy, atualize para CoddyKit PRO. O curso de Java Academy inclui 4 aulas no total.
O que vou aprender em “NumberFormat e printf”?
Formate números para exibição usando NumberFormat, DecimalFormat e padrões de printf. Você pratica Java Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Java Academy?
Nenhuma experiência prévia é necessária. Java Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.
Quanto tempo leva a aula “NumberFormat e printf”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Java Academy?
Sim. Cada aula de Java Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Fundamentos da Classe Math
- Aritmética de Inteiros e Estouro
- BigDecimal para Cálculos Financeiros
- NumberFormat e printf