Sprintf équivalent en Java

Printf a été ajouté à Java avec la version 1.5 mais je n’arrive pas à trouver comment envoyer la sortie vers une chaîne plutôt qu’un fichier (ce que fait sprintf en C). Est-ce que quelqu’un sait comment faire ça?

// Store the formatted ssortingng in 'result' Ssortingng result = Ssortingng.format("%4d", i * j); // Write the result to standard output System.out.println( result ); 

Voir le format et sa syntaxe

@erickson.

Les chaînes sont des types immuables. Vous ne pouvez pas les modifier, ne renvoyez que de nouvelles instances de chaîne.

À cause de cela, “foo” .format () a peu de sens, car il faudrait l’appeler comme

 ssortingng newSsortingng = "foo".format(); 

Les auteurs java originaux (et les auteurs de .NET), ont décidé qu’une méthode statique avait plus de sens dans cette situation, car vous ne modifiiez pas “foo”, mais appeliez plutôt une méthode de format et transmettiez une chaîne d’entrée.

EDIT : Heh, ce site peut être si amusant parfois. J’ai été condamné à mentionner le fait que les chaînes sont des types immuables.

Voici un exemple de pourquoi Format () serait stupide en tant que méthode d’instance. Dans .NET (et probablement en Java), Replace () est une méthode d’instance.

Tu peux le faire:

  "I Like Wine".Replace("Wine","Beer"); 

Cependant, rien ne se passe, car les chaînes sont immuables. Replace essaie de renvoyer une nouvelle chaîne, mais elle n’est affectée à rien.

Cela provoque beaucoup d’erreurs de recrue communes comme:

 // Consortingved Example inputText.Replace(" ","%20"); 

Encore une fois, rien ne se passe, à la place vous devez faire:

 inputText = inputText.Replace(" ","%20"); 

Maintenant, si vous comprenez que les chaînes sont immuables, cela est parfaitement logique. Si vous ne le faites pas, alors vous êtes simplement confus. L’emplacement approprié pour Remplacer serait où Format est, en tant que méthode statique de Ssortingng:

  inputText = Ssortingng.Replace(inputText," ", "%20"); 

Maintenant, il n’y a plus de question sur ce qui se passe.

La vraie question est: pourquoi les auteurs de ces frameworks ont-ils décidé que l’un devrait être une méthode d’instance, et l’autre statique? À mon avis, les deux sont plus élégamment exprimés en tant que méthodes statiques, mais erickson semble penser que les deux sont des méthodes d’instance.

Indépendamment de votre opinion, la vérité est que vous êtes moins enclin à faire une erreur en utilisant la version statique, et le code est plus facile à comprendre (No Hidden Gotchas).

Bien sûr, il existe des méthodes parfaites comme méthodes d’instance, prenez Ssortingng.Length ()

 int length = "123".Length(); 

Dans cette situation, il est évident que nous n’essayons pas de modifier “123”, nous l’inspectons simplement et renvoyons sa longueur … C’est un candidat idéal pour une méthode d’instance.

Mes règles simples pour les méthodes d’instance sur les objects immuables:

  • Si vous devez renvoyer une nouvelle instance du même type, utilisez une méthode statique.
  • Sinon, utilisez une méthode d’instance.

Les deux solutions fonctionnent pour simuler printf, mais de manière différente. Par exemple, pour convertir une valeur en chaîne hexadécimale, vous disposez des 2 solutions suivantes:

  • avec format() , le plus proche de sprintf() :

     final static Ssortingng HexChars = "0123456789abcdef"; public static Ssortingng getHexQuad(long v) { Ssortingng ret; if(v > 0xffff) ret = getHexQuad(v >> 16); else ret = ""; ret += Ssortingng.format("%c%c%c%c", HexChars.charAt((int) ((v >> 12) & 0x0f)), HexChars.charAt((int) ((v >> 8) & 0x0f)), HexChars.charAt((int) ((v >> 4) & 0x0f)), HexChars.charAt((int) ( v & 0x0f))); return ret; } 
  • avec replace(char oldchar , char newchar) , un peu plus rapide mais assez limité:

      ... ret += "ABCD". replace('A', HexChars.charAt((int) ((v >> 12) & 0x0f))). replace('B', HexChars.charAt((int) ((v >> 8) & 0x0f))). replace('C', HexChars.charAt((int) ((v >> 4) & 0x0f))). replace('D', HexChars.charAt((int) ( v & 0x0f))); ... 
  • Il y a une troisième solution qui consiste à append le caractère à ret un par un (les caractères sont des nombres qui s’ajoutent !) Comme dans:

     ... ret += HexChars.charAt((int) ((v >> 12) & 0x0f))); ret += HexChars.charAt((int) ((v >> 8) & 0x0f))); ... 

… mais ce serait vraiment moche.