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

175

Ich frage mich, warum die Methode String.valueOf(int i)existiert? Ich benutze diese Methode zur Umwandlung intin Stringund nur die entdeckte Integer.toString(int i)Methode.

Nachdem ich mir die Implementierung dieser Methoden angesehen hatte, sah ich, dass die erste die zweite aufruft. Infolgedessen beinhalten alle meine Anrufe String.valueOf(int i)einen Anruf mehr als einen direkten AnrufInteger.toString(int i)

Manuel Selva
quelle

Antworten:

46

Nur zwei verschiedene Arten, dasselbe zu tun. Es kann ein historischer Grund sein (kann mich nicht erinnern, ob einer vor den anderen kam).

Mipadi
quelle
22
Ja, aber wenn etwas dasselbe tut, heißt das nicht, dass es dasselbe ist.
Damian Leszczyński - Vash
3
String.valueOf (int) ruft Integer.toString (i) direkt auf. Rufen Sie am besten Integer.toString (int) auf.
Djchapm
171

Im String-Typ haben wir mehrere Methoden 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) 

Wie wir sehen können, können diese Methoden alle Arten von Zahlen auflösen

Jede Implementierung einer bestimmten Methode, wie Sie sie vorgestellt haben: Also für ganze Zahlen haben wir

Integer.toString(int i)

für doppelt

Double.toString(double d)

und so weiter

Meiner Meinung nach ist dies keine historische Sache, aber es ist für einen Entwickler nützlicher, die Methode valueOfaus der String-Klasse als aus dem richtigen Typ zu verwenden, da dies zu weniger Änderungen führt, die wir vornehmen müssen.

Probe 1:

public String doStuff(int num) {

  // Do something with num...

  return String.valueOf(num);

 }

Beispiel 2:

public String doStuff(int num) {

 // Do something with num...

 return Integer.toString(num);

 }

Wie wir in Beispiel 2 sehen, müssen wir im Gegensatz zu Beispiel eins zwei Änderungen vornehmen.

In meinem Fazit ist die Verwendung der valueOfMethode aus der String-Klasse flexibler und deshalb dort verfügbar.

Damian Leszczyński - Vash
quelle
18
Und vergessen Sie nicht, Integer.toString(int i, int radix)dass dies in andere Basen als 10 umgewandelt wird.
Stephen P
@Vash Könnten Sie bitte auch erklären, wie Sie mit leerem String int in String konvertieren, verglichen mit String.valueOf? zB) "" + int i = "i"? Welches das Beste ist ?
Kanagavelu Sugumar
1
Um int als Zeichenfolge zu formatieren, sollten Sie nicht "" + i verwenden. Es gibt keine großen über Kopf, aber im Allgemeinen, weil dies nicht elegant ist. Anstatt zu verwenden String.valueOf(int), können Sie String.format("%d",i);mehr lesen, besuchen Sie bitte diese Website docs.oracle.com/javase/6/docs/api/java/util/Formatter.html
Damian Leszczyński - Vash
Ich wünschte, Autoboxing wäre klüger und hätte nur die Konvertierung beim Kompilieren oder so hinzugefügt.
Rob Grant
1
@RobertGrant Das Autoboxing ist hier nicht der Fall. Aber um Ihre Bedenken zu beantworten, ist es klug, dies zu tun int i = new Integer("1");und umgekehrt.
Damian Leszczyński - Vash
52

Ein großer Unterschied besteht darin, dass Sie beim Aufrufen toString()eines Null-Objekts ein Zeichen erhalten, NullPointerExceptionwährend String.valueOf()Sie bei Verwendung möglicherweise nicht nach Null suchen.

Eine Costa
quelle
46
Die Frage ist Integer.toString(int i)eine staticMethode. Es sind keine nullObjekte möglich.
Petr Janeček
14
Integer i = null; i.toString(); // Null pointer exception!! String.valueOf(i); // No exception
manish_s
10
@ Manis Kumar: Ihr Beispiel wird die String.valueOf(int i)Methode aber nicht auslösen String.valueOf(Object obj). Wie auch immer, die Frage betrifft primitive intWerte, für die es keine Möglichkeit gibt null.
Hleinone
1
@manish_s Aus dem Beispiel ging ziemlich klar hervor, dass niemand über den Objekttyp Integer spricht. Wir sprechen nur über Primitive.
Daniel Ochoa
2
@manish_s: Die OP hat nicht gesagt , Integer.toString()aber Integer.toString(int i). Dies ist eine statische Methode ( docs.oracle.com/javase/7/docs/api/java/lang/… ).
LarsH
13

Die String-Klasse bietet valueOf-Methoden für alle primitiven Typen und Objekttypen, daher gehe ich davon aus, dass es sich um praktische Methoden handelt, auf die alle über die eine Klasse zugegriffen werden kann.

NB Profilerstellungsergebnisse

Durchschnittlicher intToString = 5368 ms, durchschnittlicher stringValueOf = 5689 ms (für 100.000.000 Operationen)

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
quelle
7
Ihre Profilerstellung sollte wirklich eine "Aufwärmphase" haben, da sonst die Ergebnisse durch das Basteln der JIT verzerrt werden können. Das heißt, ein Unterschied von 300 ms über 10 ^ 8 Operationen ist so gering, dass er völlig vernachlässigbar ist.
Cameron Skinner
1
@Kingo Ich glaube nicht, dass dein Testfall korrekt ist. Weil Sie den Wert zuweisen, ihn String jaber niemals verwenden. Der zugrunde liegende Compiler hat dies möglicherweise optimiert. Es ist besser, j Objekt in einer anderen Methode zu übergeben und eine Dummy-Operation durchzuführen.
Rakesh
1
Sie sollten auf diese Weise wirklich keine selbst entwickelten Mikro-Benchmarks schreiben. Wenn Sie JMH verwenden . Es kümmert sich um Aufwärmen, Zeitmessung, mehrere unabhängige Versuche (Forks Java!) Und macht den Code klein, wie es aussieht (inkl. Ergebnisse für verschiedene Methoden und Werte - Laufzeit 7 Minuten): gist.github.com/ecki/ 399136f4fd59c1d110c1 (Spoiler: "" + n won).
eckes
5
Danke Kumpel, aber meine Antwort war vor 5 Jahren! JMH wurde erst 2013 veröffentlicht: P
Kingo
9

Aus den Java-Quellen:

/**
 * 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);
}

Sie geben also genau das gleiche Ergebnis und einer nennt den anderen. String.valueOf ist flexibler, wenn Sie den Typ später ändern.

Davio
quelle
8

Wenn Sie sich den Quellcode für die StringKlasse ansehen , wird er Integer.toString()beim Aufruf tatsächlich aufgerufenvalueOf() .

That being said, Integer.toString()vielleicht ein bisschen schneller sein , wenn die Methodenaufrufe nicht bei der Kompilierung optimiert sind (was sie wahrscheinlich sind).

tskuzzy
quelle
Ja und "" + n ist noch schneller. Siehe gist.github.com/ecki/399136f4fd59c1d110c1
eckes
3

Die Implementierung String.valueOf(), die Sie sehen, ist der einfachste Weg, um den in der API angegebenen Vertrag zu erfüllen: "Die Darstellung ist genau die, die von der Integer.toString()Methode eines Arguments zurückgegeben wird."

Müllgott
quelle
2

Um die OP-Frage zu beantworten, ist es einfach ein Helfer-Wrapper, den anderen Anruf zu erhalten, und es kommt auf die Wahl des Stils an, und das ist es. Ich denke, hier gibt es viele Fehlinformationen, und das Beste, was ein Java-Entwickler tun kann, ist, sich die Implementierung für jede Methode anzusehen. In jeder IDE sind es nur ein oder zwei Klicks. Sie werden deutlich sehen, dass String.valueOf(int)das einfach anruftInteger.toString(int) .

Daher gibt es absolut keinen Unterschied, da beide einen Zeichenpuffer erstellen, die Ziffern in der Zahl durchlaufen, diesen dann in einen neuen String kopieren und zurückgeben (daher erstellen sie jeweils ein String-Objekt). Der einzige Unterschied besteht in einem zusätzlichen Aufruf, den der Compiler ohnehin für einen einzelnen Aufruf eliminiert.

Es ist also nicht wichtig, was Sie aufrufen, außer vielleicht Code-Konsistenz. In Bezug auf die Kommentare zu Nullen wird ein Grundelement verwendet, daher kann es nicht null sein! Sie erhalten einen Fehler beim Kompilieren, wenn Sie das übergebene Int nicht initialisieren. Es gibt also keinen Unterschied, wie Nullen behandelt werden, da sie in diesem Fall nicht vorhanden sind.

Steve J.
quelle
Könnten Sie bitte Ihren Text in einige Blöcke unterteilen. Es ist sehr schwer zu lesen.
Magnilex
Es gibt viele falsch informierte Dinge in diesem OP. Dein Beitrag ist die beste Antwort für mich! Vielen Dank
aksappy
1

Sie sollten sich keine Sorgen über diesen zusätzlichen Anruf machen, der Sie Effizienzprobleme kostet. Wenn es irgendwelche Kosten gibt, werden sie minimal sein und sollten im Gesamtbild der Dinge vernachlässigbar sein.

Vielleicht liegt der Grund, warum beide existieren, in der Lesbarkeit. Im Zusammenhang mit vielen Typen, in die konvertiert wird, Stringsind verschiedene Aufrufe von String.valueOf(SomeType)möglicherweise besser lesbar als verschiedene SomeType.toStringAufrufe.

Polygenschmierstoffe
quelle
1
Tatsächlich werden solche einzeiligen Anrufe ziemlich schnell eingebunden.
Tassos Bassoukos
Auch in einer Schleife, die 1 000 000 Mal aufruft String.valueof () ??
Manuel Selva
@Manuel: hast du es profiliert? Haben Sie festgestellt, dass hier Ihr Leistungsproblem liegt? Sind Sie sicher, dass Sie nicht vorzeitig optimieren? @Tassos: Ja, das ist auch sehr wahrscheinlich, aber so oder so würde ich mir darüber keine Sorgen machen, es sei denn, die Profilerstellung besagt, dass es ein Problem mit diesem bestimmten Aufruf gibt.
Polygenelubricants
Eigentlich, Manuel, würde ich erwarten, dass eine Schleife, die 1000000 Mal läuft, öfter inline wird als nur ein- oder zweimal. Trotzdem wird es ein kleiner Teil der Zeit sein, egal wie oft es sich wiederholt.
CorsiKa
Nein, aber ich bin mir sicher, dass meine App keinen Flaschenhals enthält. Ich frage dies nur, weil ich hier keine Bedenken hinsichtlich der Lesbarkeit sehe und daher denke ich, dass ich den optimaleren Code verwenden muss, selbst wenn die Verstärkung 0 ist. Stimmen Sie nicht zu?
Manuel Selva
1

Meine Öffnung ist valueof () und wird für die Darstellung immer als tostring () bezeichnet. Für die Darstellung des primitiven Typs wird valueof verallgemeinert. Java unterstützt standardmäßig keinen Datentyp, definiert jedoch seine Arbeit mit Objekt und Klasse, die alles in cllas gemacht und gemacht hat object .here Integer.toString (int i) erstellt ein Limit für die Konvertierung nur für Ganzzahlen.

anuragsingh
quelle
1

Es gibt keine Unterschiede zwischen Integer.toString (5) und String.valueOf (5).

weil String.valueOf Folgendes zurückgibt:

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

etc..

Ahamadullah Saikat
quelle
0

Mit der Methode String.valueOf () müssen Sie sich keine Gedanken über die Daten machen (ob int, long, char, char [], boolean, Object). Sie können einfach Folgendes aufrufen:

  • statischer String valueOf ()

Mit der einzigen Syntax kann String.valueOf () alles, was Sie als Parameter übergeben, in String konvertieren und zurückgeben.

Wenn Sie andernfalls Integer.toString (), Float.toString () usw. (dh SomeType.toString ()) verwenden, müssen Sie den Datentyp des Parameters überprüfen, den Sie in einen String konvertieren möchten. Daher ist es besser, String.valueOf () für solche Konvertierungen zu verwenden.

Wenn Sie ein Array von Objektklassen haben, das verschiedene Werte wie Integer, Char, Float usw. enthält, können Sie mithilfe der String.valueOf () -Methode die Elemente eines solchen Arrays einfach in eine String-Form konvertieren. Wenn Sie dagegen SomeType.toString () verwenden möchten, müssen Sie zunächst die Datentypklassen kennen (möglicherweise mithilfe des Operators "instanceOf"), und dann können nur Sie eine Typumwandlung durchführen.

Die aufgerufene String.valueOf () -Methode stimmt mit dem übergebenen Parameter überein (ob Integer, Char, Float usw.) und ruft bei Verwendung der Methodenüberladung die Methode "valueOf ()" auf, deren Parameter übereinstimmt, und innerhalb dieser Methode ist sie ein direkter Aufruf der entsprechenden "toString ()" - Methode.

Wir können also sehen, wie der Aufwand für das Überprüfen des Datentyps und das anschließende Aufrufen der entsprechenden "toString ()" - Methode beseitigt wird. Wir müssen nur die String.valueOf () -Methode aufrufen, ohne uns darum zu kümmern, was in String konvertiert werden soll.

Schlussfolgerung: Die String.valueOf () -Methode hat ihre Bedeutung nur auf Kosten eines weiteren Aufrufs.

Amit Bhandari
quelle
-3

toString ()

  1. ist in der Objektklasse vorhanden und wird in der abgeleiteten Klasse im Allgemeinen überschrieben
  2. Für den Aufruf der toString () -Methode ist eine Typumwandlung in die entsprechende Klasse erforderlich.

Wert von()

  1. Überladene statische Methode in der String-Klasse vorhanden.
  2. behandelt sowohl primitive Typen als auch Objekttypen.

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

Überprüfen Sie diesen Link, es ist sehr gut. http://code4reference.com/2013/06/which-one-is-better-valueof-or-tostring/

Shruti
quelle