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 <javaMethode class="java.lang.Object" methode="equals()" />.
String a = "coucou";String b = "coucou";String c = "bonjour";String d = c;a==b;<comment>FAUX, a et b sont des instances différentes de String.Ce résultat est théorique, car certains compilateurs pourraient optimiserle code pour ne créer qu'une seule instance mémoire</comment>a.equals(b); <comment>VRAI, equals() compare les chaînes caractère par caractère.</comment>c==d; <comment>VRAI, c et d représentent la même instance mémoire de String</comment>
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 <javaMethode class="java.lang.String" methode="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.
String a = "coucou"; <comment>1ère instance</comment>String b = "coucou"; <comment>2ème instance</comment>a=a.intern();<comment>l'instance 1 est ajoutée à la liste, 'a' ne change pas de valeur</comment>b = b.intern();<comment>Equivalent à : b = a;</comment>a==b;<comment>VRAI</comment>
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 : <javaClass class="java.lang.Integer" />, <javaClass class="java.lang.Double" />, <javaClass class="java.lang.Float" />, <javaClass class="java.lang.Long" />, <javaClass class="java.lang.Byte" />. La chaîne ne doit contenir que le nombre à convertir : toute erreur lève l'exception <exception locate="SUN_API">java.lang.NumberFormatException</exception>.
Exemple :
int i = Integer.parseInt(maString);long l = Long.parseLong(maString);byte b = Byte.parseByte(maString);<comment>etc...</comment>
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.
NumberFormat monFormatteurDeNombre = NumberFormat.getInstance();<br />
<comment>par défaut localisation France sur mon ordinateur</comment><br />
String maChaine = "1053,52";<br />
double resultat = monFormatteurDeNombre.parse(maChaine).doubleValue();
<comment>Le parse doit catcher l'exception ParseException</comment>
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 : <javaClass class="java.lang.Integer" />, <javaClass class="java.lang.Double" />, <javaClass class="java.lang.Float" />, <javaClass class="java.lang.Long" />, <javaClass class="java.lang.Byte" />.
Dans un premier temps, on crée un objet <javaClass class="java.text.DecimalFormat" />, puis on utilise cet objet pour convertir chaque valeur en chaîne de caractères.
Exemple de conversion d'un réel avec seulement 2 décimales :
DecimalFormat df = new DecimalFormat("########.00");System.out.println(df.format(mon_nombre));
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...
<comment>IMPORT</comment>import java.util.Locale;import java.text.DateFormat;<comment>1. Choix de la langue</comment>Locale locale = Locale.getDefault();<comment>2. Construction du DateFormat en choisiant un format :SHORT = 01/01/2002FULL = lundi 1 janvier 2002</comment>DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.FULL, locale);<comment>3. Affichage</comment>System.out.println(dateFormat.format(maDate));
Si vous souhaitez utiliser un format de sortie plus exotique, vous pouvez accéder directement à la classe <javaClass class="java.text.SimpleDateFormat" />.
DateFormat dateFormat = new SimpleDateFormat("hh'h'mm dd-MM-yy"); <comment>résultat : "23h59 31-12-2000"</comment>
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 :
publicstatic 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 <javaClass class="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.
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 <javaClass class="java.lang.String"/>
tryString chaine = "Ma chaîne à traduire !";<comment>traduction en tableau de code ASCII :</comment>byte[] bytes = chaine.getBytes("ASCII");<comment>affichage à l'écran :</comment>for( int i=0; i<bytes.length; i++ )System.out.println( bytes[i] );catch( java.io.UnsupportedEncodingException e )<comment> Le codage n'est pas reconnu.</comment>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 <javaClass class="java.nio.charset.Charset"/> pour plus d'informations)
Il faut utiliser un objet <javaClass class="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 <javaClass class="java.lang.String" /> grâce à la méthode <javaMethode class="java.lang.String" methode="split(java.lang.String)" parametres="(regex)" />.
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.
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.
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 <javaClass class="java.lang.StringBuffer"/> (en savoir plus).
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 revè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.
String resultat = ""; <comment>création d'un chaine vide</comment>for( int i=0; i<10; i++)resultat = resultat + i;System.out.println(resultat);<comment>"0123456789"</comment>
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 <javaClass class="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...
StringBuffer sb = new StringBuffer(20); <comment>20 = une estimation de la taille maximale de notre chaîne.</comment>for( int i=0; i<10; i++)sb.append(i);System.out.println(sb.toString());<comment>"0123456789"</comment>
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.
Note :
Si vous ne précisez pas la taille maximale ou que vous sous-estimez cette taille, StringBuffer 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.
Ce document issu de http://www.developpez.com est soumis à la licence GNU FDL traduit en français ici.
Permission vous est donnée de distribuer, modifier des copies de cette page tant que cette note apparaît clairement.