Java – NumberFormat est seulement un parseur de String ?
Quand on rencontre la classe NumberFormat en Java, en général c’est pour parser un objet String. Mais cette classe ne sert pas qu’à parser des chaînes de caractères !
Tout le monde sait faire :
String numberAsString = "12345"; int numberAsLong = NumberFormat.getInstance().parse(numberAsString);
Mais l’utilité du NumberFormat ne s’arrête pas là. Car comme son nom l’indique, il formate des nombres. Par exemple, il peut servir à padder avec des zéros un nombre[1]. Malheureusement, il n’est pas rare de trouver ce genre de code :
int numberAsInt = 12345; int size = 8; String numberAsString = String.valueOf(numberAsInt); while ( numberAsString.length()<size) { numberAsString = "0" + numberAsString; }
Ou une version dite améliorée
proposerait ceci :
int numberAsInt = 12345; int size = 8; StringBuffer numberAsStringBuffer = new StringBuffer(size); numberAsStringBuffer.append(numberAsInt); while ( numberAsStringBuffer.length()<size) { numberAsStringBuffer.insert(0,0); } String numberAsString = numberAsStringBuffer.toString();
Alors qu’il est tellement plus simple de faire :
int numberAsInt = 12345; int size = 8; NumberFormat nf = NumberFormat.getInstance(); nf.setMinimumIntegerDigits(size); nf.setGroupingUsed(false); String numberAsString = nf.format(numberAsInt);
Un dernier point auquel il faut faire attention ou qui peut être intéressant. La classe NumberFormat permet de spécifier la taille maximale de la représentation d’un nombre. Par exemple, pour padder sur 8 positions le nombre 12345, le résultat est 00012345. Par contre, qu’en est-il pour le nombre 1234567890 ? Avec le code ci-dessus, le résultat est la chaine « 1234567890 ». Par contre si la représentation doit avoir une longueur de strictement 8 caractères, il faut utiliser le code suivant :
int numberAsInt = 1234567890; int size = 8; NumberFormat nf = NumberFormat.getInstance(); nf.setMinimumIntegerDigits(size); nf.setMaximumIntegerDigits(size); nf.setGroupingUsed(false); String numberAsString = nf.format(numberAsInt);
Il faut faire attention, car dans ce cas la représentation sur 8 caractères n’est pas équivalente au nombre initial. Puisque les chiffres en trop sont tronqués à gauche. La représentation ainsi obtenue est « 34567890 ».
Selon les cas, cette astuce peut être intéressante ou dangereuse. Dans tous les cas, cette piqure de rappel sur le formatage des nombres ne fait pas de mal. Et il n’est pas inutile de rappeler qu’il est toujours instructif de consulter la JavaDoc !
Notes
[1] En d’autres termes, compléter à gauche un nombre avec des zéros non significatifs.
https://blog.lecacheur.com/2006/02/22/java-numberformat-est-seulement-un-parseur-de-string/Java EEQuand on rencontre la classe NumberFormat en Java, en général c'est pour parser un objet String. Mais cette classe ne sert pas qu'à parser des chaînes de caractères ! Tout le monde sait faire : String numberAsString = '12345'; int numberAsLong = NumberFormat.getInstance().parse(numberAsString); Mais l'utilité du NumberFormat ne s'arrête pas là. Car comme...SeBSébastien LECACHEUR23r0@laposte.netAdministratorLe weblogue de SeB
C’est marrant de voir toutes les lignes qu’il faut écrire en JAVA pour formater un nombre, alors qu’une ligne suffit avec un vieux et vulgaire printf en C.
Sympa comme principe !
Pour le padding, toutefois je prefere l’utilisation des jakarta-commons avec leur StringUtils.paddingleft()
PHPGuy,
Je serais tenté de dire qu’avec Java 5, il est possible de formater un nombre comme en C avec un System.out.println(). Mais ce ne serait pas honnête de ne pas préciser qu’il faudrait au préalable rediriger le flux System.out vers le flux adéquate pour récupérer ensuite la chaîne. L’écriture n’est donc pas forcément plus simple.
Il ne faut pas oublier qu’en C, il faut tout d’abord allouer la mémoire puis la libérer. Donc le travaille de formatage de nombre ne s’arrête pas à un simple sprintf(). Attention, je ne crache pas sur le C. Je programme pas mal en C également, même si celà ne se voit pas trop sur ce weblogue. 😉
Julien,
Merci pour cette précision. N’étant pas un grand utilisateur de l’API Commons Lang du projet Jakarta, je n’ai pas pensé à en parler.
Ta solution est très simple et efficace. Elle est a recommander, surtout si la bibliothèque Commons Lang est déja présente dans le projet pour lequel il faut formater des nombres.
Bon, le post est vieux, mais il est haut sur ma requête Google… 😀
Deux remarques :
– dans la première ligne de code, numberAsString est utilisée comme une fonction…
– les autres lignes de code sont trop longues et débordent sur la colonne de droite, il faudrait passer à la ligne.
Philippe,
Merci pour tes remarques. J’ai corrigé l’erreur du numberAsString. Et j’ai revu les lignes de code qui n’ont plus de retour à la ligne depuis que je suis passé de DotClear à WordPress.