Frage

Wie multipliziere ich 10 mit an Integer widersprechen und das zurückbekommen Integer Objekt?

Ich suche nach der saubersten Möglichkeit, dies zu tun.

Ich würde es wahrscheinlich so machen:Holen Sie sich int von Integer Objekt, multiplizieren Sie es mit dem anderen int und erstellen Sie ein weiteres Integer-Objekt mit diesem int-Wert.

Code wird etwa so aussehen ...

integerObj = new Integer(integerObj.intValue() * 10);

Aber ich habe einen Code gesehen, in dem der Autor es so macht:Bekommen das String von dem Integer Objekt, verketten Sie „0“ am Ende und erhalten Sie dann Integer Objekt durch Verwendung zurückgeben Integer.parseInt

Der Code sieht etwa so aus:

String s = integerObj + "0";
integerObj = Integer.parseInt(s);

Gibt es irgendeinen Vorteil darin, es so oder so zu tun?

Und was wäre im Allgemeinen und in diesem Fall der effizienteste/sauberste Weg?

War es hilfreich?

Lösung

Mit Java 5 Autoboxen, können Sie einfach Folgendes tun:

Integer a = new Integer(2); // or even just Integer a = 2;
a *= 10;
System.out.println(a);

Andere Tipps

Der String-Ansatz ist amüsant, aber mit ziemlicher Sicherheit eine schlechte Vorgehensweise.

Den int-Wert einer Ganzzahl zu erhalten und eine neue zu erstellen, geht sehr schnell, während der Aufruf von parseInt ziemlich teuer wäre.

Insgesamt würde ich Ihrem ursprünglichen Ansatz zustimmen (der, wie andere bereits betont haben, ohne so viel Unordnung durchgeführt werden kann, wenn Sie über Autoboxing verfügen, wie es in Java 5 eingeführt wurde).

Das Problem bei der zweiten Möglichkeit ist die Art und Weise, wie Strings in Java behandelt werden:

  • "0" wird zur Kompilierungszeit in ein konstantes String-Objekt konvertiert.
  • Jedes Mal, wenn dieser Code aufgerufen wird, s wird als neues String-Objekt erstellt und javac konvertiert diesen Code in String s = new StringBuilder().append(integerObj.toString()).append("0").toString() (StringBuffer für ältere Versionen).Auch wenn Sie dasselbe verwenden integerObj, d.h.,

    String s1 = integerObj + "0"; String s2 = integerObj + "0";

    (s1 == s2) wäre false, während s1.equals(s2) wäre true.

  • Integer.parseInt interne Anrufe new Integer() jedenfalls, weil Integer ist unveränderlich.

Übrigens ist das Autoboxing/Unboxing intern dasselbe wie die erste Methode.

Halten Sie sich vom zweiten Ansatz fern. Die beste Wahl wäre das Autoboxing, wenn Sie Java 1.5 verwenden. Alles, was früher als Ihr erstes Beispiel wäre, wäre am besten.

Die Lösung mit der String-Methode ist aus verschiedenen Gründen nicht so gut.Einige davon sind ästhetische Gründe, andere sind praktischer Natur.

Aus praktischer Sicht werden mit der String-Version mehr Objekte erstellt als mit der normaleren Form (wie Sie in Ihrem ersten Beispiel ausgedrückt haben).

Aus ästhetischer Sicht denke ich, dass die zweite Version die Absicht des Codes verschleiert, und das ist fast genauso wichtig wie dafür zu sorgen, dass er das gewünschte Ergebnis liefert.

Die obige Antwort von Toolkit ist richtig und der beste Weg, aber sie gibt keine vollständige Erklärung dessen, was passiert.Vorausgesetzt Java 5 oder höher:

Integer a = new Integer(2); // or even just Integer a = 2;
a *= 10;
System.out.println(a); // will output 20

Sie müssen wissen, dass dies genau das Gleiche ist wie:

Integer a = new Integer(2); // or even just Integer a = 2;
a = a.intValue() * 10;
System.out.println(a.intValue()); // will output 20

Indem Sie die Operation (in diesem Fall *=) für das Objekt „a“ ausführen, ändern Sie nicht den int-Wert innerhalb des „a“-Objekts, sondern weisen „a“ tatsächlich ein neues Objekt zu.Dies liegt daran, dass „a“ automatisch entpackt wird, um die Multiplikation durchzuführen, und dann das Ergebnis der Multiplikation automatisch entpackt und „a“ zugewiesen wird.

Integer ist ein unveränderliches Objekt.(Alle Wrapper-Klassen sind unveränderlich.)

Nehmen Sie zum Beispiel diesen Code:

static void test() {
    Integer i = new Integer(10);
    System.out.println("StartingMemory: " + System.identityHashCode(i));
    changeInteger(i);
    System.out.println("Step1: " + i);
    changeInteger(++i);
    System.out.println("Step2: " + i.intValue());
    System.out.println("MiddleMemory: " + System.identityHashCode(i));
}

static void changeInteger(Integer i) {
    System.out.println("ChangeStartMemory: " + System.identityHashCode(i));
    System.out.println("ChangeStartValue: " + i);
    i++;
    System.out.println("ChangeEnd: " + i);
    System.out.println("ChangeEndMemory: " + System.identityHashCode(i));
}

Die Ausgabe wird sein:

StartingMemory: 1373539035
ChangeStartMemory: 1373539035
ChangeStartValue: 10
ChangeEnd: 11
ChangeEndMemory: 190331520
Step1: 10
ChangeStartMemory: 190331520
ChangeStartValue: 11
ChangeEnd: 12
ChangeEndMemory: 1298706257
Step2: 11
MiddleMemory: 190331520

Sie können sehen, dass sich die Speicheradresse für „i“ ändert (Ihre Speicheradressen werden unterschiedlich sein).

Jetzt machen wir einen kleinen Test mit Reflektion und fügen dies am Ende der test()-Methode hinzu:

System.out.println("MiddleMemory: " + System.identityHashCode(i));
try {
    final Field f = i.getClass().getDeclaredField("value");
    f.setAccessible(true);
    f.setInt(i, 15);
    System.out.println("Step3: " + i.intValue());
    System.out.println("EndingMemory: " + System.identityHashCode(i));
} catch (final Exception e) {
    e.printStackTrace();
}

Die zusätzliche Ausgabe wird sein:

MiddleMemory: 190331520
Step2: 15
MiddleMemory: 190331520

Sie können sehen, dass sich die Speicheradresse für „i“ nicht geändert hat, obwohl wir ihren Wert mithilfe von Reflektion geändert haben.
(VERWENDEN SIE REFLEXION IM ECHTEN LEBEN NICHT AUF DIESE WEISE!!)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top