web-dev-qa-db-fra.com

String.format () vs "+" opérateur

Que faut-il utiliser pour une opération de concaténation de chaîne de base?

String randomString = "hello " + userName + " how are you" ?

ou

String randomString = String.format("hello %s how are you ?",userName);

Je pense que String.format() donne une meilleure idée de la chaîne de sortie . Mais que sont réellement pour et contre en utilisant l’un d’eux?

Existe-t-il quelque chose en termes de performances ou d'entrées orphelines dans le pool de littéraux de chaîne?.

Edit : Je parle de plusieurs paramètres dans la chaîne, pas un seul. Autour de 5 +.

Question bonus : S'il vous plaît, partagez également votre point de vue sur Lequel devrait-il réellement utiliser? n'importe lequel de ceux-ci ou le 3ème ... !! ?

20
Priyank Doshi

Si vous recherchez uniquement des performances, j’estime que l’utilisation de StringBuilder/StringBuffer est le moyen le plus efficace de créer des chaînes. Même si le compilateur Java est suffisamment intelligent pour traduire la plupart des concaténations de chaînes en équivalents StringBuilder.

Si vous recherchez la lisibilité, le String.format est bien plus clair, et c’est ce que j’utilise aussi, sauf si je dois miser sur des performances élevées.

Ainsi, si votre principale préoccupation n'est pas la performance, c'est-à-dire que ce code ne se trouve pas dans un chemin appelé beaucoup, vous préférerez peut-être utiliser String.format car il donne une meilleure idée de la chaîne résultante (comme vous l'avez dit).

De plus, utiliser String.format vous permet d'utiliser le format, ce qui signifie que vous pouvez l'utiliser pour le remplissage de chaînes, le formatage de nombres, les dates, etc., ce qui rendrait le code encore pire si vous utilisiez une simple concaténation.

Edit _ ​​pour Chuu:

En utilisant JAD , vous pouvez voir que le code suivant:

public class Test {
    public static void main(String[] args) {
        String str = "a" + "b" + "c";
        String str2 = "foo" + str + "bar" + str;
        System.out.println(str2);
    }
}

quand décompilé va ressembler à:

public class Test {
    public static void main(String[] args) {
        String str = "abc";
        String str2 = new StringBuilder("foo").append(str).append("bar").append(str).toString();
        System.out.println(str2);
    }
}

La preuve de cela peut également être trouvée en utilisant l'utilitaire javap qui vous montrera le bytecode Java sous un fichier .class

public static void main(Java.lang.String[] args);
    0  ldc <String "abc"> [16]
    2  astore_1 [str]
    3  new Java.lang.StringBuilder [18]
    6  dup
    7  ldc <String "foo"> [20]
    9  invokespecial Java.lang.StringBuilder(Java.lang.String) [22]
   12  aload_1 [str]
   13  invokevirtual Java.lang.StringBuilder.append(Java.lang.String) : Java.lang.StringBuilder [25]
   16  ldc <String "bar"> [29]
   18  invokevirtual Java.lang.StringBuilder.append(Java.lang.String) : Java.lang.StringBuilder [25]
   21  aload_1 [str]
   22  invokevirtual Java.lang.StringBuilder.append(Java.lang.String) : Java.lang.StringBuilder [25]
   25  invokevirtual Java.lang.StringBuilder.toString() : Java.lang.String [31]
   28  astore_2 [str2]
   29  getstatic Java.lang.System.out : Java.io.PrintStream [35]
   32  aload_2 [str2]
   33  invokevirtual Java.io.PrintStream.println(Java.lang.String) : void [41]
   36  return
20
Alex

Que faut-il utiliser pour une opération de concaténation de chaîne de base?

Les exemples que vous fournissez au serveur ont des objectifs différents. + est surchargé pour concaténer Strings mais String.format est utilisé pour formater les chaînes, comme le nom le spécifie. 

La concaténation de chaînes n'est pas son travail principal.

Donc, si l'exigence est simplement de concaténer, utilisez + ou concat method.

Ces liens seront utiles:

Dois-je utiliser String.format () de Java si les performances sont importantes?

Est-il préférable d'utiliser String.format sur la chaîne de concaténation en Java?

6
Azodious

Essaye ça

    long t0 = System.currentTimeMillis();
        String userName = "test";
        for (int i = 0; i < 1000000; i++) {
            String randomString = "hello " + userName + " how are you?";
//          String randomString = String.format("hello %s how are you ?",userName);
        }
        System.out.println(System.currentTimeMillis() - t0);

vous serez surpris de savoir que la concaturation est 10 fois plus rapide que String.format. Mais le format peut faire beaucoup de choses extrêmement utiles avec des nombres, des dates, etc. Voir l'API Java.util.Formatter, qui est utilisée par String.format, pour plus de détails.

3
Evgeniy Dorofeev

Mes deux cents: utilisez toujours String.format()

L'internationalisation est une préoccupation beaucoup plus grande que le style ou la performance dans cette situation. Pour cette raison, j'utiliserais toujours String.format()

Texte anglais: "Hello " + userName + " how are you?"

Traduction en Jedi: userName + "you are how? Hello!"

Si les chaînes sont concaténées, il peut être difficile, voire impossible, de modifier l'ordre des mots pour le traducteur. Ce problème devient de plus en plus grave car il y a plus de morceaux dans la chaîne et plus d'espaces réservés.

2
njr101

La plupart des gens qui recommandent d’utiliser StringBuffer vivent dans le passé… .. La meilleure pratique actuelle consiste à utiliser un StringBuilder. Mais cela pourrait changer, alors pourquoi ne pas laisser le compilateur le faire pour vous? deviendra un seul "foobar").

Le seul endroit où j'allouerais explicitement un StringBuilder est dans les boucles (où il est créé avant la boucle et utilisé à l'intérieur).

Vérifiez le Bytecode généré si vous avez un doute sur ce qui se passe.

Alors, quand utiliser le format? Je voudrais utiliser le format lorsque le formatage est compliqué. Mais vous parlez de simple concaténation en ce moment.

1
Fabian Lange

À mon avis, utilisez + operator.

Si les performances sont une préoccupation, vous devriez utiliser StringBuilder et, comme Alex l'a souligné dans son commentaire ci-dessus, le compilateur Java convertira: 

String str2 = "a" + str1; 

à: String str2 = new StringBuilder("a").append(str1)).toString();

En plus de cela, vous pouvez éviter les exceptions d'exécution en utilisant le + operator. Au lieu de cela, vous obtiendrez des erreurs de syntaxe que vous pourrez détecter au moment de la compilation. Par exemple:

    String var = "huge success.";

    System.out.print( "I'm making a note here: " + var );
    //System.out.print( "Printing: " + ); Syntax error!

    System.out.print( String.format( "I'm making a note here: '%s'", var ) );
    System.out.print( String.format( "I'm making a note here: '%s'" ) ); // runtime exception!
    System.out.print( String.format( "I'm making a note here: '%d'", var ) ); // runtime exception!

La lisibilité dépend des préférences personnelles. Cependant, je dirai que la syntaxe String.format provient essentiellement de C++ et que la plupart des langages créés depuis ont adopté le + operator pour des raisons de lisibilité.

1
rhinoinrepose

Personnellement, je préférerais utiliser le formatage, car il a l'air meilleur et je ne peux pas l'imaginer avoir un impact important sur les performances.

1
Duane

Je pense que String.Format est plus efficace, car il présente les avantages suivants,

  1. Lisibilité améliorée
  2. Mieux traduisible
  3. Vous pouvez utiliser des fournisseurs de format et des indicateurs de format simples (comme une largeur fixe) directement dans la chaîne de format.
  4. Vous pouvez faire des choses puissantes en plaçant des chaînes de format dans les fichiers de configuration.
  5. String.Format () est souvent plus rapide, car il utilise un StringBuilder et une machine à états efficace en coulisse, alors que la concaténation de chaînes dans .Net est relativement lente. Cela est d'autant plus vrai que la taille de la chaîne et le nombre de valeurs substituées augmentent.

Merci.

1
Chets

Ma principale préoccupation avec String.format est qu'il s'agit d'une opération spécifique aux paramètres régionaux et que vous risquez d'obtenir des résultats imprévus si votre code est exécuté dans des paramètres régionaux différents.

J'aimerais avoir une alternative non-locale car sa syntaxe compacte est vraiment agréable.

0
Agustí Sánchez