Integer.toString (int i) vs String.valueOf (int i)

176

Je me demande pourquoi la méthode String.valueOf(int i)existe? J'utilise cette méthode pour convertir inten Stringet juste découvert la Integer.toString(int i)méthode.

Après avoir regardé l'implémentation de ces méthodes, j'ai vu que la première appelle la seconde. En conséquence, tous mes appels String.valueOf(int i)impliquent un appel de plus que d'appeler directementInteger.toString(int i)

Manuel Selva
la source
3
Juste à titre de référence: stackoverflow.com/questions/3335685/integer-tostring
Bobby

Réponses:

46

Juste deux façons différentes de faire la même chose. Cela peut être une raison historique (je ne me souviens pas si l'un est venu avant l'autre).

mipadi
la source
22
Oui, mais si quelque chose fait la même chose, cela ne veut pas dire que c'est la même chose.
Damian Leszczyński - Vash
3
String.valueOf (int) appelle simplement Integer.toString (i) directement. Il est donc préférable d'appeler Integer.toString (int).
djchapm
171

Dans le type String, nous avons plusieurs méthodes valueOf

static String   valueOf(boolean b) 
static String   valueOf(char c) 
static String   valueOf(char[] data) 
static String   valueOf(char[] data, int offset, int count) 
static String   valueOf(double d) 
static String   valueOf(float f) 
static String   valueOf(int i) 
static String   valueOf(long l) 
static String   valueOf(Object obj) 

Comme nous pouvons le voir, ces méthodes sont capables de résoudre toutes sortes de nombres

chaque implémentation de méthode spécifique comme vous l'avez présentée: Donc, pour les entiers, nous avons

Integer.toString(int i)

pour double

Double.toString(double d)

etc

À mon avis, ce n'est pas quelque chose d'historique, mais il est plus utile pour un développeur d'utiliser la méthode valueOfde la classe String que du type approprié, car cela entraîne moins de modifications à apporter.

Échantillon 1:

public String doStuff(int num) {

  // Do something with num...

  return String.valueOf(num);

 }

Échantillon2:

public String doStuff(int num) {

 // Do something with num...

 return Integer.toString(num);

 }

Comme nous le voyons dans l'exemple 2, nous devons faire deux changements, contrairement à l'exemple 1.

Dans ma conclusion, l'utilisation de la valueOfméthode de la classe String est plus flexible et c'est pourquoi elle y est disponible.

Damian Leszczyński - Vash
la source
18
Et n'oubliez pas que Integer.toString(int i, int radix)cela sera converti en chaînes de bases autres que 10.
Stephen P
@Vash Pourriez-vous s'il vous plaît également expliquer comment utiliser une chaîne vide pour convertir un int en chaîne par rapport à String.valueOf? par exemple) "" + int i = "i"? Quel est le meilleur?
Kanagavelu Sugumar
1
Pour formater int sous forme de chaîne, vous ne devez pas utiliser le "" + i. Il n'existe pas de gros over head mais généralement car ce n'est pas élégant. Au lieu d'utiliser String.valueOf(int), vous pouvez utiliser String.format("%d",i);pour en savoir plus s'il vous plaît visitez ce site Web docs.oracle.com/javase/6/docs/api/java/util/Formatter.html
Damian Leszczyński - Vash
Je souhaite que l'autoboxing soit plus intelligent et que je viens d'ajouter la conversion lors de la compilation ou quelque chose du genre.
Rob Grant
1
@RobertGrant L'autoboxing n'est pas le cas ici. Mais pour répondre à vos préoccupations, il est intelligent car vous pouvez le faire int i = new Integer("1");et vice versa.
Damian Leszczyński - Vash
52

Une énorme différence est que si vous invoquez toString()dans un objet null, vous obtiendrez un NullPointerExceptionalors, en utilisant String.valueOf()vous ne pouvez pas vérifier null.

Une Costa
la source
46
La question porte sur Integer.toString(int i)une staticméthode. Il n'y a aucun nullobjet possible.
Petr Janeček
14
Integer i = null; i.toString(); // Null pointer exception!! String.valueOf(i); // No exception
manish_s
10
@Manis Kumar: Votre exemple ne déclenchera pas la String.valueOf(int i)méthode mais String.valueOf(Object obj). Quoi qu'il en soit, la question porte sur les intvaleurs primitives , là où il n'y a aucune possibilité null.
hleinone
1
@manish_s il était assez clair d'après l'exemple que personne ne parle du type d'objet Integer. Nous ne parlons que de primitifs.
Daniel Ochoa
2
@manish_s: Le PO n'a pas dit Integer.toString()mais Integer.toString(int i). C'est une méthode statique ( docs.oracle.com/javase/7/docs/api/java/lang/… ).
LarsH
13

La classe String fournit des méthodes valueOf pour tous les types primitifs et le type Object, donc je suppose que ce sont des méthodes pratiques auxquelles toutes peuvent accéder via la classe unique.

NB Profilage des résultats

Moyenne intToString = 5368 ms, moyenne stringValueOf = 5689 ms (pour 100 000 000 opérations)

public class StringIntTest {


    public static long intToString () {
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 100000000; i++) {
            String j = Integer.toString(i);
        }
        long finishTime = System.currentTimeMillis();

        return finishTime - startTime;
    }

    public static long stringValueOf () {

        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 100000000; i++) {
            String j = String.valueOf(i);
        }
        long finishTime = System.currentTimeMillis();

        return finishTime - startTime;
    }

    public static void main(String[] args) {
        long intToStringElapsed = 0;
        long stringValueOfElapsed = 0;
        for (int i = 0; i < 10; i++) {
            intToStringElapsed += intToString();
            stringValueOfElapsed+= stringValueOf();
        }
        System.out.println("Average intToString = "+ (intToStringElapsed /10));
        System.out.println("Average stringValueOf = " +(stringValueOfElapsed / 10));
    }
}
Kingo
la source
7
Votre profilage devrait vraiment avoir une période "d'échauffement", sinon les résultats peuvent être faussés par le JIT bricolant les choses. Cela dit, une différence de 300 ms sur 10 ^ 8 opérations est si petite qu'elle est complètement négligeable.
Cameron Skinner
1
@Kingo Je ne pense pas que votre cas de test soit correct. Parce que vous attribuez la valeur à String jmais ne l'utilisez jamais. Le compilateur sous-jacent peut avoir optimisé cela. Il est préférable de passer l'objet j dans une méthode différente et d'effectuer une opération factice.
Rakesh
1
Vous ne devriez vraiment pas écrire de micro benchmarks de cette façon. Si vous utilisez JMH . Il s'occupera du préchauffage, de la mesure du temps, de plusieurs essais indépendants (forks Java!) Et rend le code petit, il ressemble (y compris les résultats pour différentes méthodes et valeurs - durée d'exécution 7 minutes): gist.github.com/ecki/ 399136f4fd59c1d110c1 (spoiler: "" + n gagné).
eckes
5
Merci mon pote, mais ma réponse remonte à 5 ans! JMH n'est sorti qu'en 2013: P
Kingo
9

À partir des sources Java:

/**
 * Returns the string representation of the {@code int} argument.
 * <p>
 * The representation is exactly the one returned by the
 * {@code Integer.toString} method of one argument.
 *
 * @param   i   an {@code int}.
 * @return  a string representation of the {@code int} argument.
 * @see     java.lang.Integer#toString(int, int)
 */
public static String valueOf(int i) {
    return Integer.toString(i);
}

Donc, ils donnent exactement le même résultat et l'un appelle en fait l'autre. String.valueOf est plus flexible si vous pouvez modifier le type ultérieurement.

Davio
la source
8

Si vous regardez le code source de la Stringclasse, il appelle en fait Integer.toString()lorsque vous appelez valueOf().

Cela étant dit, cela Integer.toString()pourrait être un peu plus rapide si les appels de méthode ne sont pas optimisés au moment de la compilation (ce qu'ils sont probablement).

tskuzzy
la source
Oui et "" + n est encore plus rapide. Voir gist.github.com/ecki/399136f4fd59c1d110c1
eckes
3

L'implémentation de ce String.valueOf()que vous voyez est le moyen le plus simple de respecter le contrat spécifié dans l'API: "La représentation est exactement celle renvoyée par la Integer.toString()méthode d'un argument."

trashgod
la source
2

Pour répondre à la question des OP, c'est simplement un wrapper d'aide pour avoir l'autre appel, et cela revient au choix de style et c'est tout. Je pense qu'il y a beaucoup de désinformation ici et la meilleure chose qu'un développeur Java puisse faire est de regarder l'implémentation de chaque méthode, c'est à un ou deux clics dans n'importe quel IDE. Vous verrez clairement que cela vous String.valueOf(int)appelle simplement Integer.toString(int).

Par conséquent, il n'y a absolument aucune différence, en ce sens qu'ils créent tous les deux un tampon de caractères, parcourent les chiffres du nombre, puis copient cela dans une nouvelle chaîne et la renvoient (par conséquent, chacun crée un objet String). La seule différence est un appel supplémentaire, que le compilateur élimine de toute façon en un seul appel.

Donc, peu importe ce que vous appelez, à part peut-être la cohérence du code. Quant aux commentaires sur les nulls, il faut une primitive, donc il ne peut pas être nul! Vous obtiendrez une erreur de compilation si vous n'initialisez pas l'int en cours de transmission. Il n'y a donc aucune différence dans la façon dont il gère les valeurs nulles car elles n'existent pas dans ce cas.

Steve J
la source
Pourriez-vous s'il vous plaît séparer votre texte en quelques blocs. C'est très difficile à lire.
Magnilex
Il y a beaucoup de choses mal informées dans ce PO. Votre message est la meilleure réponse pour moi! Merci
aksappy
1

Vous ne devriez pas vous inquiéter du fait que cet appel supplémentaire vous coûte des problèmes d'efficacité. S'il y a un coût, ce sera minime et devrait être négligeable dans une vue d'ensemble des choses.

Peut-être que la raison pour laquelle les deux existent est d'offrir une lisibilité. Dans le contexte de nombreux types en cours de conversion String, divers appels à String.valueOf(SomeType)peuvent être plus lisibles que divers SomeType.toStringappels.

lubrifiants polygènes
la source
1
En fait, ces appels sur une seule ligne sont intégrés assez rapidement.
Tassos Bassoukos
Même dans une boucle appelant 1 000 000 fois String.valueof () ??
Manuel Selva
@Manuel: l'avez-vous profilé? Avez-vous identifié ici votre problème de performance? Êtes-vous sûr de ne pas optimiser prématurément? @Tassos: oui, c'est aussi très probable, mais de toute façon je ne m'en soucierais pas à moins que le profilage ne dise qu'il y a un problème avec cet appel en particulier.
polygenelubricants
En fait, Manuel, je m'attendrais à ce qu'une boucle allant 1000000 fois soit intégrée plus souvent qu'une ou deux fois. Même ainsi, ça va être une petite partie du temps, peu importe le nombre de boucles.
corsiKa
Non, mais je suis sûr qu'il n'y a pas de goulot de bouteille ici dans mon application. Je pose simplement cette question parce que je ne vois aucun problème de lisibilité ici et donc je pense que je dois utiliser le code le plus optimal même si le gain est de 0. Vous n'êtes pas d'accord?
Manuel Selva
1

mon ouverture est valueof () toujours appelée tostring () pour la représentaion et donc pour la représentation du type primitif valueof est généralisée.et java par défaut ne prend pas en charge le type de données mais définit son travail avec objaect et class son fait tout dans cllas et fait object .here Integer.toString (int i) crée une limite de conversion pour uniquement un entier.

anuragsingh
la source
1

Il n'y a aucune différence entre Integer.toString (5) et String.valueOf (5);

car String.valueOf renvoie:

public static String valueOf(int i) {
    return Integer.toString(i);
}
public static String valueOf(float f) {
    return Float.toString(f);
}

etc..

Ahamadullah Saikat
la source
0

En utilisant la méthode String.valueOf (), vous n'avez pas à vous soucier des données (qu'elles soient int, long, char, char [], boolean, Object), vous pouvez simplement appeler:

  • static String valueOf ()

en utilisant la seule syntaxe String.valueOf () peut tout ce que vous passez en paramètre est converti en String et renvoyé.

Sinon, si vous utilisez Integer.toString (), Float.toString () etc. (ie SomeType.toString ()) alors vous devrez vérifier le type de données du paramètre que vous voulez convertir en chaîne. Il est donc préférable d'utiliser String.valueOf () pour de telles conversions.

Si vous avez un tableau de classe d'objets qui contient différentes valeurs comme Integer, Char, Float, etc., alors en utilisant la méthode String.valueOf (), vous pouvez convertir facilement les éléments d'un tel tableau en forme de chaîne. Au contraire, si vous voulez utiliser SomeType.toString (), vous aurez d'abord besoin de connaître leurs classes de types de données (peut-être en utilisant l'opérateur "instanceOf") et ensuite vous seul pouvez procéder à un transtypage.

La méthode String.valueOf () lorsqu'elle est appelée correspond au paramètre qui est passé (que ce soit son Integer, Char, Float, etc.) et en utilisant la surcharge de méthode appelle cette méthode "valueOf ()" dont le paramètre est mis en correspondance, puis à l'intérieur de cette méthode, c'est un appel direct à la méthode "toString ()" correspondante.

Ainsi, nous pouvons voir comment la surcharge liée à la vérification du type de données et à l'appel de la méthode "toString ()" correspondante est supprimée. Il suffit d'appeler la méthode String.valueOf (), sans se soucier de ce que nous voulons convertir en String.

Conclusion: La méthode String.valueOf () a son importance juste au prix d'un appel supplémentaire.

Amit Bhandari
la source
-3

toString ()

  1. est présent dans la classe Object, généralement remplacé dans la classe dérivée
  2. typecast à la classe appropriée est nécessaire pour appeler la méthode toString ().

valeur de()

  1. Méthode statique surchargée présente dans la classe String.
  2. gère les types primitifs ainsi que les types d'objets.

    Integer a = null;
    System.out.println(Integer.toString()) ; NUll pointer exception
    System.out.println(String.valueOf() ; give NULL as value

vérifiez ce lien c'est très bon. http://code4reference.com/2013/06/which-one-is-better-valueof-or-tostring/

shruti
la source