Les FAQs Java :
FAQ JAVA FAQ Java EE FAQ Java ME FAQ Java XML FAQ JavaFX FAQ Java GUI FAQ Struts FAQ JSF FAQ JDBC JDO FAQ Hibernate FAQ Spring FAQ Eclipse FAQ NetBeans FAQ JCreator FAQ Maven 2

FAQ JavaConsultez toutes les FAQ

Nombre d'auteurs : 53, nombre de questions : 231, dernière mise à jour : 26 janvier 2014 

 
OuvrirSommaireGénéralitésGestion des nombres et chaînes de caractères

Avant d'essayer de comparer deux chaînes de caractères, il faut bien comprendre que l'opérateur '==' permet de comparer entre eux les types primitifs (int, float, boolean, etc. ) mais dans le cas des objets, cet opérateur compare les emplacements mémoire des objets : deux instances initialisées avec les mêmes paramètres occupent un espace mémoire différent, elles sont donc différentes du point de vue de '=='. L'opération qui permet de comparer les objets entre eux est la méthode equals() de java.lang.Object.

 
Sélectionnez

String a = "coucou";
String b = "coucou";
String c = "bonjour";
String d = c;
 
a==b;
/** FAUX, a et b sont des instances différentes de String.
 * Ce résultat est théorique, car certains compilateurs pourraient optimiser
 * le code pour ne créer qu'une seule instance mémoire
 */
 
a.equals(b); 
// VRAI, equals() compare les chaînes caractère par caractère.
 
c==d; 
// VRAI, c et d représentent la même instance mémoire de String 

JDK 1.4, méthode 'intern()'
Le JDK 1.4 vient un peu compliquer la chose en conservant une liste privée d'instances de String. Initialement, la liste est vide. L'appel de la méthode intern() cherche dans la liste si une instance est égale d'après 'equals()', si oui, cette instance est retournée, sinon la chaîne est ajoutée à la liste.

 
Sélectionnez

 
String a = "coucou"; // 1ère instance 
String b = "coucou"; // 2ème instance 
a=a.intern(); // l'instance 1 est ajoutée à la liste, 'a' ne change pas de valeur 
b = b.intern(); // Equivalent à : b = a; 
 
a==b; // VRAI 
Créé le 10 novembre 2002  par Clément Cunin

Par défaut, toutes les opérations de comparaisons et égalités des chaînes de caractères se basent sur leurs valeurs unicodes. Cela permet des traitements très rapides car il s'agit d'une comparaison bit à bit, mais cela produit des résultats non-souhaitables avec certaines locales...

Prenons par exemple le code suivant qui permet de trier une liste et de l'afficher :

 
Sélectionnez
List list = new ArrayList();
list.add("oxygène");
list.add("");
list.add("ou");
Collections.sort(list);
 
System.out.println(list);

On pourrait s'attendre à obtenir un résultat par ordre alphabétique, c'est à dire : "ou, où, oxygène". Or on obtient le résultat suivant :

 
Sélectionnez
[ou, oxygène, où]

Ce résultat est dû au fait que le tri s'effectue sur la valeur unicode des caractères. Or le caractère 'ù' prend la valeur 249 alors que 'u' et 'x' ont respectivement les valeurs 117 et 120. Ce qui fait que le caractère 'x' vient s'intercaler entre les caractères 'u' et 'ù', ce qui peut être gênant dans une langue comme le français où les accents ont une certaine importance.

Pour remédier à cela, il faut utiliser la classe Collator, qui permet d'effectuer des comparaisons en prenant en compte la locale :

 
Sélectionnez
Collections.sort(list, Collator.getInstance(Locale.FRANCE));

La méthode statique Collator.getInstance() permet de créer une nouvelle instance de Collator pour la locale. Le Collator implémente l'interface Comparable afin de comparer les chaînes de caractères.

De plus, les Collators permettent également de fixer des contraintes plus ou moins fortes concernant la comparaison des caractères, et permet de définir 4 niveaux via la méthode setStrength() :

  • IDENTICAL : Les caractères doivent être strictement identiques.
  • TERTIARY : Diminue les contraintes de IDENTICAL en ignorant les différences sur les caractères de contrôles (ex: \u0001 == \u0002).
  • SECONDARY : Diminue les contraintes de TERTIARY en ignorant les différences de case minuscule/majuscule (ex: 'a' == 'A').
  • PRIMARY : Diminue les contraintes de TERTIARY en ignorant les accents (ex: 'a' == 'à' == 'â' == 'ä' == 'A' == 'Ä' etc.)

Attention toutefois, étant données que les Collators se basent sur des règles plus complexes, ils peuvent prendre plus de temps que la comparaison standard des chaînes.

Mis à jour le 29 octobre 2008  par adiGuba

Lien : How should I compare String objects?
Lien : java.text.Collator

Méthode parseXXX()
La conversion de chaînes de caractères en valeurs numériques est assurée par les différentes classes de gestion des types de base de Java : java.lang.Integer, java.lang.Double, java.lang.Float, java.lang.Long, java.lang.Byte. La chaîne ne doit contenir que le nombre à convertir : toute erreur lève l'exception java.lang.NumberFormatException.

Exemple :

 
Sélectionnez

 
int i = Integer.parseInt(maString);
long l = Long.parseLong(maString);
byte b = Byte.parseByte(maString);
// etc... 

Pour convertir une chaîne hexadécimale en entier il faut utiliser la méthode suivante:

 
Sélectionnez

Integer.parseInt(hexa, 16);

Le 16 spécifie la base à utiliser pour parser l'entier.

Méthode XXXXFormat.parse(pattern)
Une autre méthode, plus lourde mais aussi plus flexible consiste à utiliser un Formatter pour parser la chaîne en nombre. Cette méthode vous permet de parser les nombres en tenant compte de l'internationalisation du séparateur décimal.

 
Sélectionnez

NumberFormat monFormatteurDeNombre = NumberFormat.getInstance();
// par défaut localisation France sur mon ordinateur
String maChaine = "1053,52";
double resultat = monFormatteurDeNombre.parse(maChaine).doubleValue();
// Le parse doit catcher l'exception ParseException 
Mis à jour le 12 octobre 2006  par Clément Cunin

Lien : Comment convertir un nombre en chaîne ?

Methode toString(valeur)
La conversion de chaîne de caractères en valeurs numériques est assurée par les différentes classes de gestion des types de base de Java : java.lang.Integer, java.lang.Double, java.lang.Float, java.lang.Long, java.lang.Byte.

Exemple :

 
Sélectionnez

String chaine = Integer.toString(monInt);
String chaine = Long.toString(monLong);
String chaine = Byte.toString(monByte);
// etc...
Mis à jour le 3 mai 2002  par Clément Cunin

Lien : Comment convertir une chaîne en nombre ?
Lien : Comment convertir un nombre en chaîne formatée ?


La classe java.text.DecimalFormat permet de formater une valeur numérique dans le format de son choix en utilisant un pattern dont les symboles principaux sont les suivants :

  • 0 permet de représenter un chiffre qui devra obligatoirement être présent, même s'il s'agit d'un zéro inutile.
  • # permet de représenter un chiffre en ignorant les zéros inutiles.
  • . (le point) permet de représenter le séparateur de la partie décimale.
  • , (la virgule) permet de représenter le séparateur des groupes (milliers, millions, etc.).


(vous pouvez vous reporter à la documentation de la classe DecimalFormat pour obtenir la liste complète de tous les symboles).


Le nombre de 0 et/ou de # dans le pattern détermine la taille des parties entière et décimale de la valeur numérique, sachant que 0 représentera un chiffre obligatoirement présent (et éventuellement remplacé par un zéro inutile) et # un chiffre optionnel (qui ignorera donc les zéro inutile).


Par exemple, pour afficher un nombre réel avec 2 décimales, on utilisera le code suivant :

 
Sélectionnez
DecimalFormat df = new DecimalFormat("0.00");
System.out.println(df.format(mon_nombre));


Vous trouverez dans le tableau suivant quelques exemples de pattern :

Format 0 0,02 0,8 12,9
# 0 0 1 13
### 0 0 1 13
0 0 0 1 13
000 000 000 001 013
#.## 0 0,02 0,8 12,9
0.## 0 0,02 0,8 12,9
0.00 0,00 0,02 0,80 12,90
#.00 ,00 ,02 ,80 12,90
#,##0.00 0,00 0,02 0,80 12,90


Par défaut, la partie entière sera toujours agrandit même si le pattern précise un nombre d'élément moins important.


A noter que toutes les caractéristiques du pattern peuvent être modifié par les méthodes de la classe DecimalFormat, et que la classe NumberFormat permet d'obtenir un certain nombre de formatage standard via des méthodes statiques.


Enfin, à partir de Java 5.0 il est possible d'utiliser une syntaxe proche du printf() du C via la classe java.util.Formatter. Dans la pratique on n'utilisera pas directement cette classe mais des méthodes l'utilisant comme PrintStream.printf() ou String.format().


Cette syntaxe différencie les types entiers (short, int, long et BigInteger) des types réels (float, double et BigDecimal).


Les types entiers sont représentés par la syntaxe %d :

 
Sélectionnez
System.out.printf ("%d", 12); // Affiche 12

Quelques exemples de formatage pour la valeur 12 :

Syntaxe Exemple Description
%d "12" Valeur entière.
] " 12" Valeur entière sur 5 caractères minimum (complété par des espaces avant le nombre).
%-5d "12 " Valeur entière sur 5 caractères minimum (complété par des espaces après le nombre).
%05d "00012" Valeur entière sur 5 chiffres minimum, complété par des zéros.


Les types réels sont quand à eux représentés par la syntaxe %f :

 
Sélectionnez
System.out.printf ("%f", 1234.567); // Affiche 1234,567000


Quelques exemples de formatage pour la valeur 1234.567 :

Syntaxe Exemple Description
%f "1234,567000" Valeur réelle avec 6 décimales par défaut.Valeur réelle avec 6 décimales par défaut. Valeur réelle avec 6 décimales par défaut.
_ "1234,567000" Valeur réelle sur 5 caractères minimum (partie entière + décimale).
%.0f "1235" Partie entière sans décimale.
%.2f "1234,57" Valeur réelle avec 2 décimales.
%2F " 1234,57" Valeur réelle sur 10 caractères minimum, avec 2 décimales
%,.2f "1 234,57" Valeur réelle avec 2 décimales et séparateur de millier.


Note : il est possible d'utiliser des formats scientifiques et exponentielles avec %g et %e...


La documentation de la classe java.util.Formatter contient toutes les informations détaillées sur la syntaxe à utiliser.


Note : Ces deux solutions (Formatter et DecimalFormat) utilisent les spécificités de la locale par défaut pour formater la chaine (caractère de séparateur de millier, des décimales, etc.). Il est bien sûr possible de préciser une autre locale via les paramètres des méthodes ou du constructeur.

Mis à jour le 29 octobre 2008  par L'équipe Java

Lien : Comment convertir un nombre en chaîne ?
Lien : java.text.NumberFormat
Lien : java.text.DecimalFormat
Lien : java.util.Formatter

Conversion en base 2, 8, 16 : int toXXXString()

La classe Integer dispose de 3 méthodes statiques permettant de convertir un entier décimal en une chaîne représentant son équivalent binaire, octal et hexadécimal.

 
Sélectionnez

int intBase10 = 192;
String intBase2 = Integer.toBinaryString(intBase10); // "11000000"
String intBase8 = Integer.toOctalString(intBase10);  // "300"
String intBase16 = Integer.toHexString(intBase10);   // "c0"

public static String toString(int i,int base)

Afin d'obtenir la représentation dans la base de son choix d'un entier décimal, la classe Integer dispose des méthodes statiques toString().

 
Sélectionnez

int intBase10 = 19587;
String intBase2 = Integer.toString(intBase10,2);   // "100110010000011"
String intBase5 = Integer.toString(intBase10,5);   // "1111322"
String intBase27 = Integer.toString(intBase10,27); // "qnc"

Si la base n'est pas dans l'intervalle [Character.MIN_RADIX,Character.MAX_RADIX], alors la base 10 est utilisée.

Créé le 20 octobre 2006  par Nourdine Falola

Comment convertir une chaîne représentant un nombre entier en base quelconque en un entier décimal ?

La méthode statique parseInt() de la classe Integer permet de convertir une chaîne représentant un nombre entier en base quelconque en un entier décimal.

 
Sélectionnez

parseInt("99", 8)   // throws a NumberFormatException
parseInt("Kona", 10)   // throws a NumberFormatException
parseInt("Kona", 27) //returns 411787
parseInt("-0", 10) //returns 0
parseInt("-FF", 16) //returns -255
parseInt("1100110", 2) //returns 102

Integer decode(String nm) throws NumberFormatException

La méthode decode() de la classe Integer permet de convertir en Integer une chaîne vérifiant la grammaire suivante :

  • (-) DecimalNumeral
  • (-) 0x HexDigits
  • (-) 0X HexDigits
  • (-) # HexDigits
  • (-) 0 OctalDigits
Créé le 20 octobre 2006  par Nourdine Falola

La conversion d'une date en chaîne de caractères est délicate au premier abord. En effet, le format des dates est très différent d'une langue à l'autre. Heureusement, les fonctions d'internationalisation de Java vont faire le travail à notre place...

 
Sélectionnez

// IMPORT
import java.util.Locale;
import java.text.DateFormat;
 
// 1. Choix de la langue
Locale locale = Locale.getDefault();
 
/** 2. Construction du DateFormat en choisiant un format :
 * SHORT = 01/01/2002
 * FULL = lundi 1 janvier 2002
 */
DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.FULL, locale);
 
// 3. Affichage
System.out.println(dateFormat.format(maDate));

Si vous souhaitez utiliser un format de sortie plus exotique, vous pouvez accéder directement à la classe java.text.SimpleDateFormat.

 
Sélectionnez

DateFormat dateFormat = new SimpleDateFormat("hh'h'mm dd-MM-yy");
//résultat : "23h59 31-12-2000"
Créé le 9 mai 2002  par Clément Cunin

Lien : Comment convertir une date en chaîne ?

Pour convertir une chaine en date, il faut connaître le format de la date. Par défaut, une seule classe dans l'API gère les formats de date : java.text.SimpleDateFormat. On utilise le parser de date pour effectuer la conversion. Voici une méthode générique :

 
Sélectionnez

public static Date stringToDate(String sDate, String sFormat) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat(sFormat);
        return sdf.parse(sDate);
} 

Le parser déclenche l'exception ParseException quand la chaine ne respecte pas le format. La documentation sur java.text.SimpleDateFormat décrit le format d'une date, et des lettres à utiliser pour caractériser le jour, le mois, ... etc.
Cette méthode est valable à partir du JDK 1.1
Un exemple d'utilisation est fourni en téléchargement.

Mis à jour le 1er mai 2008  par Grégory Danelon

Lien : Comment convertir une date en chaîne ?
Téléchargement : Exemple d'utilisation.

Définition du type char :
Le type 'char' de Java est un type primitif, codé sur 16 bits, qui contient la valeur unicode du caractère. De plus, le type 'char' est un entier non-signé qui peut contenir des valeurs de 0-65535; Toutes les opérations arithmétiques sont légales ( voir Les spécifications du langage Java ).

Conversion en ASCII :
La manière la plus simple de passer de l'Unicode à l'ASCII est d'utiliser la classe java.lang.String.

 
Sélectionnez

try {
        String chaine = "Ma chaîne à traduire !";
 
        // traduction en tableau de code ASCII :
        byte[] bytes = chaine.getBytes("ASCII");
 
        // affichage à l'écran :
        for( int i=0; i<bytes.length; i++ ) {
                System.out.println( bytes[i] );
        } 
} catch( java.io.UnsupportedEncodingException e ) {
        // Le codage n'est pas reconnu.
        e.printStackTrace();
} 
 

Conversion dans d'autres formats :
Quelques autres formats d'encodage sont gérés par Java en interne : US-ASCII, ISO-8859-X (1 à 7), UTF-8, UTF-16BE, UTF-16LE, UTF-16. (voir la classe java.nio.charset.Charset pour plus d'informations)

Créé le 5 juin 2002  par Clément Cunin

Lien : Encodage des bytes et des chaines
Lien : Convertion des textes Non-Unicode

Pour faire cela, on peut utiliser le constructeur de String prenant en paramètre un tableau de bytes ainsi que l'encodage à utiliser.

Voici un exemple permettant de convertir une chaîne codée en UTF-8 en ISO-8859-1 (Latin 1, français)

 
Sélectionnez

byte[] bytesUTF8 = ... ; 
byte[] bytesISO = new String(bytesUTF8, "ISO-8859-1").getBytes();
Mis à jour le 7 juin 2009  par cyberzoide

JDK 1.0 :
Il faut utiliser un objet java.util.StringTokenizer qui permet aisément de découper une chaîne en sous-chaînes séparées par des délimiteurs que l'on peut préciser.

JDK 1.4 :
Le JDK 1.4 apporte la gestion des expressions régulières, le découpage d'une chaîne est maintenant possible directement de la classe java.lang.String grâce à la méthode split(java.lang.String regex).

Mis à jour le 3 mai 2002  par Clément Cunin, Jean-Baptiste Bugeaud

Rien de plus facile ! Java utilise la norme Unicode pour gérer les chaînes de caractères. Il suffit donc de se reférer au site http://www.unicode.org/charts/ et d'utiliser le code proposé sous le caractère souhaité.

Exemple :
Nous désirons afficher dans notre application le caractère ? .
Il s'agit d'un caractère de type mathématique. Une rapide étude de la liste Mathematical Operators nous permet de trouver le code 2200.

 
Sélectionnez
monJTextArea.append( "\u2200 le caractère unicode Java le connait." );

Attention :
Le résultat de l'affichage d'un caractère bizarre dans une console sous Windows ou sous Linux dépend de l'encodage supporté par la console ; dans la pratique cela marche rarement.

Créé le 27 janvier 2003  par Johann Heymes

Lien : Le site du Consortium Unicode
Lien : La page proposant les listes
Téléchargement : Exemple d'implémentation.

Les chaînes de caractères ne sont pas vraiment limitées en java. On notera cependant que les caractères de la chaîne sont indexés par des 'int', ce qui nous fixe une limite à 2^32 caractères (soit une chaîne de plus de 4Go en mémoire).

Note :
Attention, si vous manipulez des chaînes (modification, concaténation, etc ...) et à plus forte raison des chaînes de grande taille, vous devez utiliser des java.lang.StringBuffer (en savoir plus).

Créé le 1er mars 2003  par Clément Cunin

Lien : Comment concatener des chaînes de caractères ?

Théoriquement, chaque fois que l'on doit créer ou modifier une chaîne par concaténation. Dans la pratique, il est nécessaire de bien comprendre comment Java gère les chaînes de caractères et les concaténations pour manipuler efficacement les chaînes.

La classe String :
En Java, une instance de la classe String est dite non-mutable, c'est à dire qu'après avoir été créée, la chaîne ne peut plus être modifiée. Cela s'avère très pratique dans beaucoup de situations : inutile par exemple de dupliquer une instance de String pour s'assurer qu'elle restera constante (comme c'est le cas en C++ par exemple). Mais cette propriété se révèle désastreuse avec l'emploi de l'opérateur '+' pour la concaténation de chaîne, car chaque étape de la concaténation implique la construction d'une nouvelle instance de String.

 
Sélectionnez

String resultat = ""; // création d'un chaine vide
for( int i=0; i<10; i++) {
        resultat = resultat + i;
} 
System.out.println(resultat); // "0123456789" 

Lors de l'éxecution de ce programme, chaque itération de la boucle construit une nouvelle instance de String. Chaque itération oblige donc la JVM à trouver de la place en mémoire, instancier l'objet, copier le contenu des 2 chaînes dans la nouvelle, libérer la mémoire, recommencer à l'itération suivante. Cela revient à créer 10 instances de String pour les résultats intermédiaires.

La classe StringBuffer :
La classe java.lang.StringBuffer est une classe qui gère une chaîne modifiable. Cette classe a été spécialement conçue pour manipuler des chaînes de caractères...

 
Sélectionnez

StringBuffer sb = new StringBuffer(20); // 20 = une estimation de la taille maximale de notre chaîne.
for( int i=0; i<10; i++) {
        sb.append(i);
} 
System.out.println(sb.toString()); // "0123456789" 

Ce code produit exactement le même résultat que le précédent, sauf qu'il instancie un seul objet là où 10 étaient nécessaires.

La classe StringBuffer :
Depuis J2SE 5.0 (Tiger), vous pouvez aussi utiliser la classe StringBuilder (du package java.lang). Son fonctionnement est identique à celui de StringBuffer à la différence qu'il n'est pas "thread-safe". Si vous n'avez pas besoin de synchronization (comme c'est souvent le cas), préférez StringBuilder car il sera plus performant.

Note :
Si vous ne précisez pas la taille maximale ou que vous sous-estimez cette taille, StringBuffer/StringBuilder recréera automatiquement son tableau de caractères pour pouvoir accueillir votre texte, mais cette option est aussi coûteuse que la création d'une instance de String, il convient donc de choisir intelligemment cette valeur.

Mis à jour le 12 décembre 2004  par Clément Cunin

Si vous essayez ceci :

 
Sélectionnez

System.out.println(1.3-1.2); 

Vous obtenez : 0.10000000000000009 au lieu de 0.1 , comme indiqué sur votre calculatrice. En fait, il est impossible de représenter exactement 0.1 ou n'importe quelle puissance négative de 10 au moyen d'un float ou d'un double. La meilleure solution pour résoudre ce problème est d'utiliser la classe java.math.BigDecimal. On l'utilise par exemple comme ceci:

 
Sélectionnez
BigDecimal bd1 = new BigDecimal("1.3"); 
BigDecimal bd2 = new BigDecimal("1.2"); 
System.out.println(bd1.substract(bd2)); 

Attention, les chiffres que vous voulez représenter doivent être passés comme des Strings dans le constructeur

Créé le 19 juillet 2004  par duj

Arrondir un réel en entier :

Il suffit d'utiliser la méthode Math.floor() pour arrondir un réel à l'entier inférieur le plus proche :

 
Sélectionnez
double a = Math.floor(1.99); // 1.0

A l'inverse la méthode Math.ceil() permet arrondir un réel à l'entier supérieur le plus proche :

 
Sélectionnez
double a = Math.ceil(1.01); // 2.0

Si l'on souhaite respecter la règle standard de l'arrondi, en utilisant l'entier supérieur ou inférieur le plus proche selon la valeur partie décimale, il suffit d'ajouter 0.5 à la valeur passé à Math.floor() :

 
Sélectionnez
double a = Math.floor(1.99+0.5); // 2.0
 
Sélectionnez
double a = Math.floor(1.49+0.5); // 1.0
  • Si la valeur de la partie décimale est inférieure à [b]0.5[/b], la valeur sera arrondie à l'entier inférieur.
  • Si la valeur la partie décimale est supérieur ou égale à [b]0.5[/b], la valeur sera arrondie à l'entier supérieur.

Attention : on pourrait également utiliser un cast vers les types int ou long pour "perdre" la partie décimale, mais cela peut poser des problèmes avec des grandes valeurs car les cast peuvent conduire à une perte d'information par troncature.

Arrondir un réel à 'n' décimales :

On peut également faire un arrondi à 'n' décimales en utilisant le code suivant :

 
Sélectionnez
double a = 1.6666666;
	// Arrondir la valeur a 10^-2 
	a *= 100.0;
	a = Math.floor(a+0.5);
	a /= 100.0; // 1.67

Pour simplifier on peut utiliser directement cette méthode

 
Sélectionnez
/**
 * Arrondi d'un double avec n éléments après la virgule.
 * @param a La valeur à convertir.
 * @param n Le nombre de décimales à conserver.
 * @return La valeur arrondi à n décimales.
 */
public static double floor(double a, int n) {
	double p = Math.pow(10.0, n);
	return Math.floor((a*p)+0.5) / p;
}

Qui s'utilise de la manière suivante :

 
Sélectionnez
double a = floor(1.6666666, 2); // 1.67

Mais attention toutefois, on peut obtenir un résultat incorrect lorsqu'on s'approche de la limite maximum des doubles ( 1e308 quand même). Pour des résultats plus précis, on pourra se trouver vers la classe BigDecimal et ses méthodes setScale().

Arrondir pour afficher :

En revanche, si le résultat est destiné à une conversion en chaîne de caractères, il est préférable de se tourner vers la classe java.text.DecimalFormat (plus d'info ici)

Mis à jour le 29 octobre 2008  par Clément Cunin, Johann Heymes, adiGuba

Lien : Comment convertir un nombre en chaîne formatée ?

Voici la description de différents "outils" pouvant vous permettre de faire des calculs mathématiques. Les deux premiers sont des classes faisant partie du JDK standard, le dernier est une API du projet Jakarta Commons.

  • Math (package java.lang) : La classe Math contient un ensemble de méthodes statiques permettant de faire des opérations numériques basiques (logarithmes, exponentielles ou fonctions trigonométriques). Contrairement à la classe StrictMath, les différentes implémentations d'une même méthode ne donnent pas le même résultat "bit à bit". On peut quand même noter que, en général, les implémentations des méthodes de la classe Math font appel aux méthodes de StrictMath. Si la précision n'est pas le critère primordial, vous pouvez préférer Math à StrictMath pour des raisons de performance.
  • StrictMath (package java.lang) : Les méthodes de StrictMath sont les mêmes que celles de Math, à la différence que les résultats obtenus sont les mêmes que ceux produits par la fdlibm (Freely Distributable Math Library). Plus d'informations dans la description de la classe StrictMath : http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/StrictMath.html
  • Math 1.0 (Jakarta Commons) : Cette API (disponible à cette adresse : http://commons.apache.org/proper/commons-math/) met à la disposition du développeur Java un plus grand nombre d'algorithmes mathématiques et statistiques. Plus d'informations dans la documentation : http://commons.apache.org/proper/commons-math/userguide/index.html

Il en existe bien d'autres, plus d'informations sur la page API.

Mis à jour le 6 juillet 2005  par Ioan Calapodescu

Pour tout connaître de la génération de nombres aléatoires, je vous conseille de regarder cet excellent tutoriel de Hugo Etiévant : Génération de variables aléatoires uniformes, normales et exponentielles avec l'API Random de Java.

Créé le 28 janvier 2005  par Ioan Calapodescu

Lien : http://cyberzoide.developpez.com/tutoriels/java/api-java-random/

Il est utile de 'protéger' certaines chaînes de caractères avant de les utiliser dans une expression régulière. En effet, de nombreux caractères peuvent être interprétés par les regexp alors qu'on souhaite simplement représenter le caractère lui-même...

Le moyen le plus simple est de protéger ces caractères avec un anti-slash afin d'indiquer qu'ils ne doivent pas être interprétés... Toutefois, cette solution ne peut se limiter qu'à des expressions simples, et elle est complexe à mettre en place lorsque la chaîne provient d'une saisie utilisateur...

Dans ce cas, il est préférable d'utiliser les éléments de quotation \Q et \E. En effet, toute la sous-chaîne comprise entre ces deux éléments sera protégée lors de son traitement par les expressions régulières (il faut bien sûr penser à doubler l'anti-slash).

Il existe dans Java 5.0 une méthode statique permettant de protéger une chaîne simplement : Pattern.quote(String).
Pour information, cette méthode se contente généralement de renvoyer la chaîne entouré par \Q et \E. Elle gère toutefois le cas particulier où cette dernière contiendrait déjà le code \E.
Si vous n'utilisez pas encore Java 5.0, cette méthode correspond au code suivant :

La méthode Pattern.quote() :
Sélectionnez

public static String quote(String s) {
        int slashEIndex = s.indexOf("\\E");
        if (slashEIndex == -1)
            return "\\Q" + s + "\\E";
 
        StringBuffer sb = new StringBuffer(s.length() * 2);
        sb.append("\\Q");
        slashEIndex = 0;
        int current = 0;
        while ((slashEIndex = s.indexOf("\\E", current)) != -1) {
            sb.append(s.substring(current, slashEIndex));
            current = slashEIndex + 2;
            sb.append("\\E\\\\E\\Q");
        }
        sb.append(s.substring(current, s.length()));
        sb.append("\\E");
        return sb.toString();
    }
Créé le 22 août 2005  par adiGuba

Lien : Pourquoi dois-je doubler/quadrupler le caractère anti-slash ('\') ?
Lien : Documentation de la classe Pattern

Les expressions régulières permettent de créer des groupes lors d'un remplacement. Un groupe est simplement entouré de parenthèses. Ainsi, si on veut formater un texte HTML afin que toutes les occurences d'une chaîne soient entourées par une balise <strong>, on peut utiliser le code suivant :

 
Sélectionnez

String texte = "Un simple mot et un autre mot...";
String resultat = texte.replaceAll("(mot)", "<strong>$1</strong>");

Explication : Lors du remplacement, le contenu du groupe (mot) sera reporté dans la chaîne de remplacement par son indice ($1 en l'occurrence). Ainsi, dans notre exemple, le code $1 de la chaîne de remplacement sera remplacé par la chaîne "mot", pour obtenir :

 
Sélectionnez

Un simple <strong>mot</strong> et un autre <strong>mot</strong>...

Ceci est d'autant plus utile lorsqu'on utilise un pattern plus complexe. Par exemple, pour créer des balises <a href/> lorsqu'on trouve une URL dans un texte, on peut utiliser le code suivant :

Création de lien HTML pour les URL :
Sélectionnez

String texte = "Bienvenue sur http://www.developpez.com !!!";
String resultat = texte.replaceAll("(http://[^ ]*)", "<a href='$1'>$1</a>");

Il est bien sûr possible d'utiliser plus d'un groupe, l'indice dépendra alors de la position du groupe dans le texte, sachant que la lecture se fait de gauche à droite. L'expression ((A)(B(C))) donnera :

  • $1     : ABC
  • $2     : A
  • $3     : BC
  • $4     : C

Il faut bien sûr veiller à ce que tous les groupes soient correctement fermés...

Mis à jour le 1er mai 2008  par adiGuba

Lien : Documentation de la classe Pattern

Java, comme beaucoup d'autres langages, utilise le caractère anti-slash ('\') afin de représenter des caractères spéciaux, tels que \n et \t (pour le retour à la ligne et la tabulation), les quottes (\" et \') et les caractères unicodes (\u******** correspond au code unicode).

Ceci afin de pouvoir les insérer dans une String ou un char, alors qu'ils ne sont pas forcément représentable dans un code source, ou qu'ils rentreraient en conflit avec la grammaire du langage...

Ainsi, lors de la compilation, ces séquences sont transformées vers leurs caractères équivalents. Donc, afin de pouvoir utiliser le caractère anti-slash comme un simple caractère, il faut utiliser la séquence le représentant, c'est à dire \\. D'ailleurs, si une séquence commençant par \ n'est pas reconnue par le compilateur, la compilation échouera ("invalid escape sequence").

Ainsi, la chaîne "MOT1 \\ MOT2" dans le code source donnera bien MOT1 \ MOT2 lors de l'exécution du programme : pour représenter un caractère anti-slash, il faut le doubler.

Toutefois, bien qu'on ne souhaite représenter qu'un seul caractère \, il peut être parfois nécessaire de le quadrupler. En effet, le package java.util.regex permet de manipuler des Expressions régulières (ou regexp). Les expressions régulières représentent une famille de notations compactes et puissantes permettant de décrire des "modèles" (pattern) de chaînes de caractères. Elles utilisent pour cela un grand nombre de caractères spéciaux permettant de représenter d'autres ensembles de caractères (Cf. la documentation de la classe Pattern pour plus de détails). Or il se trouve que les expressions régulières utilisent le caractères anti-slash afin de 'protéger' ces caractères spéciaux, c'est à dire pour leurs permettre d'être utilisés comme de simples caractères. Donc pour représenter le caractère anti-slash il faut encore le doubler.
Etant donné que les expressions régulières interprètent la chaîne de caractère lors de l'exécution du programme, il faut donc qu'il soit quadruplé dans le code source (une fois à la compilation et une fois à l'exécution).

Exemples :

Code Source A l'exécution Interprétation des regexps
"abc\abc" Erreur de compilation : "invalid escape sequence : \a"  -
"abc\\abc" abc\abc abcabc (\a est équivalent à a pour les regexp)
"abc\\\abc" Erreur de compilation : "invalid escape sequence : \a"  -
"abc\\\\abc" abc\\abc abc\abc

Donc pour obtenir le caractère \ dans une expression régulière, il faut le quadrupler dans le code source !!!

Créé le 22 août 2005  par adiGuba

Lien : Documentation de la classe Pattern

La réponse peut sembler évidente : il suffit d'utiliser la méthode length() de la classe String.

Mais si l'on regarde de plus près, on s'aperçoit que cette méthode renvoit en réalité le nombre de char utilisés pour représenter la chaîne. Or un char en Java est codé sur 2 octets alors que les caractères Unicodes peuvent avoir une taille variable selon l'encodage et l'alphabets (entre 1 et 4 octets).

Ainsi la valeur renvoyé par la méthode length() reflète donc la taille occupée en mémoire et non pas le nombre de caractères de la chaîne (même si dans la majorité des cas le résultat sera le même).

Ainsi, afin de connaitre avec précision le nombre de caractères réels de la chaîne, il est neccéssaire d'utiliser la méthode codePointCount() de la classe String, qui permet de renvoyer le nombre de caractères Unicode entre deux emplacement de la chaîne, quel que soit leurs tailles en mémoire. Ainsi, pour connaitre le nombre de caractères effectif d'un String, il faut utiliser le code suivant :

 
Sélectionnez
String str = ... // la chaine
int count = str.codePointCount(0, str.length());

L'exemple suivant permet de mettre en évidence cette différence en utilisant une lettre gothique codé sur 4 octets :

 
Sélectionnez
String testString = "\uD800\uDF30";
int charCount = testString.length();
int characterCount = testString.codePointCount(0, charCount);
 
System.out.printf("char count: %d\n", charCount);
System.out.printf("character count: %d\n", characterCount);

Qui nous donne le résultat suivant :

 
Sélectionnez
char count: 2
character count: 1
Créé le 11 novembre 2006  par adiGuba

Lien : How long is your String object?

Pour effectuer un tirage aléatoire, il faut utiliser la classe Random. Cette classe va nous permettre d'effectuer des générations de nombre pseudo-aléatoire.

On peut tirer des chiffres de différents types : boolean, byte, double, float, int et long. Tout cela au moyen des méthodes nextXXX() de la classe Random.

Une particularité avec un tirage d'int est le fait que l'on puisse configurer la séquence sur laquelle le nombre va être tiré. On peut en effet passer un paramètre int à la méthode nextInt() qui sera le nombre maximum à tirer, le nombre minimal étant zéro.

 
Sélectionnez
Random random = new Random(); 
 
int pseudoRandomNumber = random.nextInt(); 			//Un nombre aléatoire
int pseudoRandomNumberTwo = random.nextInt(25); 	//Un nombre aléatoire entre 0 et 25
Créé le 7 janvier 2007  par Baptiste Wicht

Selon votre version de Java et vos besoins, il y a plusieurs solutions possibles à cet épineux problème.

Avec Java 6, il est possible d'utiliser la classe java.text.Normalizer afin de décomposer le codage unicode des accents en deux "caractères" :
Le premier caractère correspond à la lettre sans aucune accentuation.
Le second caractère est un "diacritique", c'est à dire un signe qui s'ajoute au caractère auquel il est associé.

Ces caractères diacritiques font partie de la plage unicode 0300-036F.
Il est donc possible de les supprimer assez facilement avec une expression régulière, par exemple :

 
Sélectionnez
	public static String sansAccents(String source) {
	return Normalizer.normalize(source, Normalizer.Form.NFD).replaceAll("[\u0300-\u036F]", "");
}

Malheureusement cette classe n'est pas présente sous cette forme dans l'API des versions précédentes de Java. En effet cette classe faisait partie de l'API propriétaire de Sun et se nommait sun.text.Normalizer.

 
Sélectionnez
public static String sansAccents(String s) {
	return Normalizer.normalize(s, Normalizer.DECOMP, 0).replaceAll("[\u0300-\u036F]", "");
}

S'il est toutefois possible de l'utiliser tel quel, il faut bien prendre en compte qu'il s'agit d'une classe "non standard/portable" qui pourrait très bien ne pas exister dans une JVM standard, et qu'il est donc fortement conseillé de ne pas utiliser.

La troisième solution consiste à utiliser une librairie externe comme ICU4J :

 
Sélectionnez
public static String sansAccents(String s) {
	Transliterator accentsconverter = Transliterator.getInstance("NFD; [:M:] Remove; NFC; ");
	return accentsconverter.transliterate(s);
}

Il s'agit toutefois d'une bibliothèque assez conséquente (plus de 4 Mo dans sa dernière version).

Enfin la dernière solution consiste tout simplement à coder manuellement une classe prévue à cet effet, comme cet exemple dans les sources Java : Supprimer les accents d'une chaine

Mis à jour le 29 octobre 2008  par divxdede
Les codes sources présentés sur cette page sont libres de droits, et vous pouvez les utiliser à votre convenance. Pour le reste, ce document constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Ce document issu de http://www.developpez.com est soumis à deux licences, en fonction des contributeurs : - Les contributions de Clément Cunin et Johann Heymes sont soumises aux termes de la la licence GNU FDL traduite en français ici. Permission vous est donnée de distribuer, modifier des copies des contributions de Clément Cunin et Johann Heymes tant que cette note apparaît clairement : "Ce document issu de http://www.developpez.com est soumis à la licence GNU FDL traduite en français ici. Permission vous est donnée de distribuer, modifier des copies de cette page tant que cette note apparaît clairement". - Pour ce qui est des autres contributions : Copyright © 2014 Developpez LLC : Tous droits réservés Developpez LLC. Aucune reproduction, ne peut en être faite sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD.