Ferramentas de Usuário

Ferramentas de Site


dev_geral:java:formatacaonumeros

Formatação e Conversão de Números

Quando se desenvolvem aplicações, seja em Java ou noutra linguagem, é comum que se lide com números que estão guardados em variáveis de texto, tipicamente porque esses números provêm de algum local externo à nossa aplicação. A conversão desse texto para o seu valor numérico é acaba por ser algo bastante comum.

Quando pretendemos mostrar números ao utilizador é importante que os mesmos sejam formatados para um aspecto que seja o esperado pelo utilizador, por exemplo, em Portugal usamos o ponto como separador dos milhares, outros países usam a vírgula.

Como podemos ver, conversões e formatações de números são operações bastante comuns no desenvolvimento de aplicações. Em Java essas tarefas são bastante simples de executar e iremos verificar isso nos parágrafos seguintes.

Strings para Valores Numéricos

Todas as classes encapsuladoras de tipos primitivos1), possuem, pelo menos, dois métodos de conversão de Strings, o método valueOf(), permite converter a String passada para um objecto encapsulador, o método parseXXX permite converter para o tipo primitivo2).

String s = "10.5";
 
Integer i = Integer.valueOf(s); //criar objecto encapsulador com o valor 10.
int i2 = Integer.parseInt(s); //obter o valor primitivo, 10.
 
Double d = Double.valueOf(s);
double d2 = Double.parseDouble(s); //obter o valor primitivo, 10.5

Converter é simples mas é necessário ter em atenção alguns aspectos:

  • a conversão é feita segundo as definições regionais do sistema operativo.
  • se a conversão falhar é lançada uma excepção de runtime que nos permite recuperar ou tratar situações de erro. Importante quando estamos a pedir valores directamente ao utilizador sem que os possamos validar primeiro.
  • os métodos parseXXX assumem, por omissão, que estamos a trabalhar com números em base 10.
try {
 
    System.out.println("Introduza um número");
    //ler input do utilizador, assumimos que o input é retomado para uma variável do tipo String chamada "in"
 
    Interger i = Integer.valueOf(in);
    int i2 = Integer.parseInt(in);
 
    Float f = Float.valueOf(in);
    float f2 = Float.parseFloat(in);
 
    Double d = Double.valueOf(in);
    Double d2 = Double.parseDouble(in);
 
} catch (NumberFormatException ex) {
    System.out.println("O valor introduzido não é um número");
}

Formatação de Números

Neste caso estamos a tentar alterar a forma de apresentação de valores que já possuímos mas que pretendemos mostrar ao utilizador. Esta A formatação recorre às classes NumberFormat e DecimalFormat ou dos métodos format() da classe PrintStream.

A classe NumberFormat é uma classe de formatação genérica, permite alterar a apresentação dos valores através do uso de máscaras, essas máscaras, compostas por um conjunto de caracteres pré-definidos, permitem especificar de que forma os nossos valores vão ser tratados, indicando o número de casas decimais, presença ou omissão do sinal3), etc.

Esta classe é abstracta e faz uso do padrão de desenho Factory para a criação das instâncias. Obter uma instância de NumberFormat implica que a JVM terá de ler um conjunto relativamente grande de opções, todas elas provenientes do nosso sistema operativo, e criar uma instância que funcione em conformidade com essas opções, se vamos formatar vários números, é vantajoso obter a instância apenas uma vez e guardar uma referência para ela.

NumberFormat nf = NumberFormat.getInstance(); //obter uma instância de NumberFormat, 
                                              //com todas as definições regionais 
                                              //do nosso Sistema operativo
nf.format(123.45); //formatar um número

Podemos querer formatar os nossos números seguindo definições regionais diferentes das introduzidas no sistema operativo4), para tal basta indicarmos qual a região que pretendemos usar.

NumberFormat nf = NumberFormat.getInstance(Locale.CHINESE); //obter uma instância de NumberFormat, 
                                                            //especificando a região usada
nf.format(123.45);

Além da classe NumberFormat, podemos usar para números decimais5), a classe DecimalFormat. Esta não é, ao contrário da sua superclasse, uma classe abstracta.

(…)

1)
classes Integer, Boolean, Double, etc.
2)
Na verdade o primeiro método recorre ao segundo para criar o objecto, podemos ver isso na implementação da classe Integer onde o método valueOf é construído através de: Integer(parseInt(s, 10));, onde "s" é a String passada.
3)
Em números positivos o sinal é omitido mas podemos quer mostrá-lo.
4)
Garantimos assim que, se necessário, a região usada não fica dependente do utilizador ter configurado correctamente o seu sistema operativo. Atenção que esta situação deverá ser seguida apenas em casos onde seja realmente justificável, de outro forma arriscamos a que a nossa aplicação não funcione como o utilizador espera.
5)
Na verdade podemos usar também para inteiros, já que estes serão um caso especial dos números decimais, podem ser vistos como um número decimal onde a componente após a vírgula é sempre zero.
dev_geral/java/formatacaonumeros.txt · Última modificação em: 2018/05/14 21:37 (edição externa)