JavaRush /Blog Java /Random-ES /Formatear la salida de números en Java

Formatear la salida de números en Java

Publicado en el grupo Random-ES
¡Hola a todos! A menudo, nuestros métodos vienen con números que deben mostrarse en algún formato especial. Parece poca cosa, pero ¿cómo implementarías esta tarea? Formatear la salida de números en Java - 1Te invitamos a pensar un poco en esto hoy. Primero, para profundizar en el formato de números en Java, recordemos el método de formato de la clase String : formato de cadena estático público (formato de cadena, objeto... args) : devuelve una cadena formateada a partir de la cadena de formato utilizando los argumentos de argumentos restantes . Y solo un ejemplo:
String str = String.format("¡Hola, %s! ¿Cómo estás %s?", "Sasha", "En el trabajo");
System.out.println(str);
Como resultado, obtendremos el resultado en la consola:
¡Hola Sasha! ¿Cómo están las cosas en el trabajo?

métodos printf y formato

String.format() no es el único método para formatear una cadena. Sus análogos son System.out.printf() y System.out.format(); . Entonces, podemos reemplazar el código anterior con:
System.out.printf("¡Hola, %s! ¿Cómo estás %s?", "Sasha", "En el trabajo");
o
System.out.format("¡Hola, %s! ¿Cómo estás %s?", "Sasha", "En el trabajo");
La salida en la consola seguirá siendo la misma. La única diferencia es que estos métodos muestran inmediatamente el valor en la consola, a diferencia de String.format() . Pero me gusta más String.format() , ya que no siempre necesitamos mostrar el resultado en la consola, por lo que usaremos este método más adelante. Volvamos a nuestro ejemplo. ¿Qué vemos? Y el hecho es que en los lugares donde había caracteres - %s , se insertan las líneas - "Sasha" y "en el trabajo" . ¿Cómo puede esto ayudarnos en el desarrollo? Imagine que tiene una plantilla de texto grande, pero en algunos lugares necesita insertar valores que pueden ser diferentes y venir como argumentos externos. Aquí es donde este formato resulta útil. Los especificadores de formato comienzan con un signo de porcentaje, %, y terminan con un carácter que indica el tipo de argumento que se va a formatear. Y, como probablemente comprenderá, %s se utiliza para insertar objetos: cadenas. Pero si intentamos insertar, por ejemplo, un doble en el lugar donde está registrado el objeto string:
String str = String.format("¡Hola, %s! ¿Cómo estás %s?", 55.6, "En el trabajo");
esto también funcionará. double se convertirá en una cadena y obtendremos:
Hola - 55,6! ¿Cómo están las cosas en el trabajo?
Además de cadenas y números de punto flotante, existen otros tipos en Java, ¿verdad? Así que echemos un vistazo a todo el arsenal:
Tipo de valor a formatear Ejemplo
%s Cualquier tipo que se convierta en una cadena.
String.format("¡Su!","mundo")
Resultado:
¡Hola Mundo!
%b Cualquier tipo que se convierta en booleano : verdadero - si el valor no es nulo, falso - si es nulo
String.format("¡Hola %b!",null)
Resultado:
hola falso
%h Puede pasar cualquier objeto, que se convertirá en una cadena de valor hexadecimal desde el método hashCode()
String.format("¡Hola %h!","mundo")
Resultado:
Hola 106c44!
%C Se utiliza para especificar un carácter Unicode ( char ).
String.format("¡Hola m%cr!",'Y')
Resultado:
¡Hola Mundo!
%d Se especifica un número entero ( int. byte, short, int, long, BigInteger )
String.format("¡Ya soy %d!",20)
Resultado:
¡Ya tengo 20!
%F Se utiliza para especificar un número de coma flotante.
String.format("PI es - %f!", 3.14159)
Resultado:
¡El número PI es 3,141590!
%mi Números de coma flotante en notación científica.
String.format("PI es - %e!", 3.14159);
Resultado:
El número PI es - 3.141590e+00.
%a Los números de coma flotante se representarán en hexadecimal.
String.format("PI es - %a!", 3.14159)
Resultado:
El número PI es: 0x1.921f9f01b866ep1.
%X Se pasa un número entero ( int. byte, short, int, long, BigInteger ), el resultado del formato será el carácter con el número dado en la tabla ASCII.
String.format("¡Ya soy %x!",25)
Resultado:
¡Ya tengo 19!
%o Se acepta un número entero ( int. byte, short, int, long, BigInteger ) y se representará como un número octal.
String.format("¡Yo ya %o!",25);
Resultado:
¡Ya tengo 31!
%t Prefijo para conversiones de fecha y hora. Se requieren indicadores adicionales para formatear
String.format("Hoy es %tA",new Date())
Resultado:
Hoy es sábado
%norte Separador de líneas específico de la plataforma. Analógico\n
String.format("Hola %n Hola")
Resultado:
hola hola
Usemos un formato más adecuado para double :
String str = String.format("La distancia de Kyiv a Odessa es %f. No es tan corta, ¿verdad?", 475.4d);
System.out.println(str);
Salida de consola:
La distancia de Kiev a Odesa es 475,400000. No tan poco, ¿verdad?
Como te habrás dado cuenta, %f sería un especificador más apropiado para números de coma flotante, que incluyen tipos de datos como double y float en Java. Con este especificador podemos formatear un número de coma flotante:
String str = String.format("La distancia de Kyiv a Odessa es %.2f. No es tan corta, ¿verdad?", 475.4d);
Insertar .2 en este especificador truncará el número de decimales a dos, lo que nos dará el resultado:
La distancia de Kiev a Odesa es 475,40. No tan poco, ¿verdad?
.2 no es el único ajuste a los especificadores. La combinación de estos subconjuntos se llama instrucción . Formatear la salida de números en Java - 2La forma general de las instrucciones es la siguiente:
%[argument_index][flags][width][.precision]especificador de tipo
Ahora descifremos todo en orden:
  • [argument_index] es un número entero que indica la posición en la lista de argumentos. Por ejemplo, el enlace al primer argumento es $1, el enlace al segundo argumento es $2, etc. Si no se especificó la posición, los argumentos deben estar en el mismo orden en que se hace referencia a ellos en la cadena de formato.
  • [banderas] son ​​caracteres especiales para formatear. Por ejemplo:
    • Bandera + que indica que si un valor numérico es positivo, debe incluir un signo +
    • - significa alinear el resultado a la izquierda
    • , establece el separador de miles para números enteros
  • [ancho] es un entero decimal positivo que especifica el número mínimo de caracteres que se generarán. Si este número está precedido por 0, los caracteres que faltan se rellenarán con 0, si no hay 0, con espacios.
  • [.accuracy] es un número entero no negativo precedido por un punto. Normalmente se utiliza para limitar el número de caracteres. El comportamiento específico depende del tipo específico de especificador.
También me gustaría señalar que todos los elementos de las instrucciones anteriores son opcionales y todo funcionará sin ellos. Como ejemplo del uso de subconjuntos, imaginemos que necesitamos una salida específica del número Pi:
String str = String.format("%1$+09.5f", 3.1415926535897);
System.out.print(str);
Y en consecuencia, la salida en la consola:
+03.14159
Parece fácil, ¿verdad? Pero cuando se trata de formatear un número, no puedes ignorar DecimalFormat . Averigüemos qué significa esto.

Formato decimal

DecimalFormat es una clase para formatear cualquier número en Java, ya sea un número entero o de punto flotante. Cuando se crea un objeto DecimalFormat , puede especificar una plantilla para formatear los números entrantes directamente en el constructor. Así es como se vería nuestro ejemplo usando DecimalFormat :
DecimalFormat dF = new DecimalFormat( "#.###" );
double value = 72.224463;
System.out.print(dF.format(value));
Salida de consola:
72.224
La línea #.### es un patrón que indica que estamos formateando el valor pasado con 3 decimales. ¿Qué otros símbolos están disponibles para los patrones? Éstos son algunos de ellos:
  • # — dígito, se omiten los ceros iniciales;
  • 0 : el dígito siempre se muestra, incluso si el número tiene menos dígitos (en este caso, se muestra 0);
  • . — signo separador decimal;
  • , — signo de agrupación separador (por ejemplo, separador de miles);
  • ; — separa formatos;
  • - — marca el prefijo de un número negativo;
  • % : multiplica por 100 y muestra el número como porcentaje;
  • ? — multiplica por 1000 y muestra el número en ppm;
  • E : separa mantisa y exponente para notación científica.
Echemos un vistazo a algunos ejemplos:
System.out.println(new DecimalFormat( "###,###.##" ).format(74554542.224463));
Salida de consola:
74.554.542,22
System.out.println(new DecimalFormat( "%###.##" ).format(0.723456));
Salida de consola:
%72,35
System.out.println(new DecimalFormat( "000.###" ).format(42.224463));
Salida de consola:
042.224
No es necesario crear un nuevo objeto DecimalFormat cada vez para definir una nueva plantilla. Será suficiente utilizar sus métodos applyPattern y applyLocalizedPattern :
DecimalFormat dF = new DecimalFormat("###.###");
dF.applyPattern("000000.000");
dF.applyLocalizedPattern("#,#00.0#");
Cuando hablamos de formatear un número de punto flotante, nos interesa mucho redondear, ¿no? Entonces, al recortar un número con decimales más allá del patrón especificado, DecimalFormat redondea el número hacia arriba si el último número recortado es mayor que 5. ¿Qué pasa si el último número recortado es 5? De hecho, en este caso, este número está exactamente en el medio entre los números enteros más cercanos. Formatear la salida de números en Java - 3En este caso se tiene en cuenta el número anterior. Si el número anterior es par se redondea:
DecimalFormat dF = new DecimalFormat("##.###");
String result = dF.format(56.4595);
System.out.println((result));
Salida de consola:
56.459
Si es impar no se realiza:
DecimalFormat dF = new DecimalFormat("##.###");
String str = dF.format(56.4595);
System.out.println((str));
Salida de consola:
56.459
La diferencia entre formatear números de coma flotante usando String.format() y DecimalFormat.format() es que en el primer caso habrá ceros finales, incluso si no hay una parte fraccionaria. Por ejemplo:
String firstStr = String.format("%.4f", 9.00001273);
System.out.println((firstStr));
Salida de consola:
9.0000
DecimalFormat decimalFormat = new DecimalFormat("#.####");
String secondStr = decimalFormat.format(9.00001273);
System.out.println((secondStr));
Salida de consola:
9
Como puede ver, al formatear el número 9.00001273 con una precisión de cuatro decimales, el método format() de la clase String generará el valor 9.0000 , mientras que el método format() similar de DecimalFormat generará 9 .

BigDecimal y BigInteger

Ya que hemos tocado el tema del redondeo de números en Java, hablemos sobre cómo usar la clase BigDecimal para tales operaciones . Esta clase está enfocada a trabajar con números realmente GRANDES: para ello, los valores máximos dobles y flotantes son demasiado pequeños. Esta clase tiene muchas configuraciones diferentes para el redondeo de punto flotante, así como muchos métodos para operaciones aritméticas. Tiene una clase similar, pero enfocada a trabajar con enteros GRANDES: BigInteger . Puede leer más sobre BigDecimal y BigInteger en este artículo .

Formatear fecha y hora

Solo se mencionó anteriormente que usando format() de la clase String también puedes formatear la hora y la fecha. Formatear la salida de números en Java - 4Bueno, echemos un vistazo a cómo se hace. Primero, nos gustaría recordarle que el especificador de formato %t se utiliza para las fechas . En segundo lugar, al formatear una plantilla, se requieren indicadores de formato adicionales para cada especificador de formato para fechas. Aquí están los posibles indicadores de formato para las fechas:
Banderas Descripción
%tuberculosis Nombre completo del mes, por ejemplo, enero, febrero, etc.
%tuberculosis Nombre abreviado del mes, por ejemplo, enero, febrero, etc.
%ejército de reserva Nombre completo del día de la semana, por ejemplo, domingo, lunes.
%ejército de reserva Nombre abreviado del día de la semana, por ejemplo, domingo, lunes, etc.
%tY Año en formato de 4 dígitos, por ejemplo, de 0000 a 9999
%ty Año en formato de 2 dígitos, por ejemplo, de 00 a 99
%tm El mes tiene el formato cero al principio, por ejemplo del 01 al 12.
%tc Fecha y hora en el formato %ta %tb %td %tT %tZ %tY, por ejemplo, lunes 17 de febrero 03:56:12 PST 2020
%tD Fecha en formato %tm/%td/%ty
%td Día del mes en formato de dos dígitos, por ejemplo del 01 al 31
% te Día del mes en formato sin 0 inicial, por ejemplo del 1 al 31
%tT Hora en formato de 24 horas, por ejemplo %tH:%tM:%tS
%th Hora del día en formato 24 horas, de 00 a 23
%tI Hora del día para un formato de 12 horas, por ejemplo, de 01 a 12
%tM Los minutos de la hora tienen el formato de un cero a la izquierda, por ejemplo, de 00 a 59.
%tS Segundos de un minuto, que constan de dos dígitos, por ejemplo, del 00 al 59
%tZ Abreviatura de zona horaria, como PST, UTC, etc.
Esta es una lista abreviada de posibles indicadores de formato de fecha; hay muchos para todos los gustos. Puede encontrar una lista completa de ellos y posibles especificadores en este enlace . Veamos cómo usar esto. Esta vez no usamos String.format() , sino inmediatamente System.out.printf() .

Ejemplo 1

Además, configuraremos el idioma del resultado pasándolo como primer argumento del método:
Date date = new Date();
System.out.printf(Locale.ENGLISH,"%tB %te, %tY",date,date,date);
Salida de consola:
11 de octubre de 2020
Sin especificar un idioma, se utilizará el idioma predeterminado (por ejemplo, tengo ruso).

Ejemplo 2

Mostremos una fecha más completa:
Date date = new Date();
System.out.printf("%td %tB %tY de %n%tH:%tM:%tS",date,date,date,date,date,date,date);
Y la salida en la consola:
11 de octubre de 2020 13:43:22
Pasar el mismo objeto Date como argumento tantas veces... No se ve muy bien, ¿verdad? Usemos el subconjunto interno $ para especificar el argumento que queremos usar:
System.out.printf("%1$td %1$tB %1$tY del año %n%1$tH:%1$tM:%1$tS",date);
La salida en nuestra consola no cambiará. Hay otras formas igualmente interesantes de formatear fechas. Puedes leer sobre ellos y un poco más sobre hora y fecha en Java en este material . Eso es todo por hoy, ¡gracias por su atención!Formatear la salida de números en Java - 5
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION