Integer.valueOf(....) vs String.hashCode()

Hallo, ich bin durch die Matrikelnummern-Diskussion auf eine interessante Frage gestoßen:

Ist bei häufigem Aufruf (in @Override public int hashCode() { )
return Integer.valueOf(string);
oder
return string.hashCode();
schneller?

Kommt drauf an was du erreichen willst.
Die beiden Aufrufe machen komplett was anderes.

Die richtige Lösung wäre in dem Fall eigentlich das Attribut für die Matrikelnummer gleich als int zu definieren und den Wert einfach als hashCode zurückzugeben.

Bei String#hashCode() wird der Wert btw nur beim ersten Aufruf berechnet und dann gecached.

Ich habe auch einen Fehler gemacht:

	return Integer.valueOf(parseInt(s, 10));
    }

    public static Integer valueOf(int i) {
        if(i >= -128 && i <= IntegerCache.high)
            return IntegerCache.cache[i + 128];
        else
            return new Integer(i);
    }```

```    public static int parseInt(String s) throws NumberFormatException {
	return parseInt(s,10);
    }```

parseInt cached also nicht und ist langsamer oder so. Oder valueOf liefert gleich ein ganzes Integer-Objekt zurück, das wird natürlich überhaupt nicht benötigt. Sowas blödes heute…

Ich bin Komplet Anfängerin, aber warum braucht man matrikelnummer int definieren? mit matrikelnummer wird doch nicht gerechnet und String kann man besser behandeln. Ich weiß wirklich nicht wie es in der Entwicklung ist.

Ein int passt in ein CPU-Register und kann dort mit minimalem Aufwand verglichen werden
„CMP Register1, Register2“
→ 1 Zeiteinheit

Bei einem String braucht man dafür mehrere Maschinenbefehle, die Speicherbereiche(Array von Zeichen) vergleichen.
→ 300 Zeiteinheiten
(sinngemäß) :stuck_out_tongue:

Was ist eine Matrikelnummer? Ist es eine Zahl? Wenn ja, dann passt ein Datentyp der eine Zahl ist (z.B. ein int) ganz gut. Wenn eine Matrkelnummer noch Buchstaben beinhaltet, dann passt ein Datentyp der ein Text ist (z.B. ein String) besser - allerdings wird dann „Integer.parseInt“ nicht mehr zuverlässig funktionieren.

Grundsätzlich ist das Umwanden von einem Typ in einen anderen immer mit Vorsicht zu geniessen, weil es eine unsichere Operation, und damit eine potenielle Fehlerquelle, ist.

Das ist egal. Warum sollte das interessant sein?

Aus genau diesem Grund würde ich die Matrikelnummer ebenfalls als String speichern. Es sei denn, es stellt sich heraus, dass die Vergleiche von Strings der Flaschenhals ist.

Premature optimization is the root of all evil.

Ich bin Komplet Anfängerin, aber warum braucht man matrikelnummer int definieren? mit matrikelnummer wird doch nicht gerechnet

Obwohl Anfängerin, hast du bereits einen sehr wichtigen Grundsatz gelernt. Wenn mit einem Wert gerechnet werden soll, dann muss man natürlich Zahltypen nehmen. Wenn nicht, sollte man es auch nicht. Auch bei Werten, die nur Ziffern enthalten, ist hier eindeutig String vorzuziehen. Einzige Ausnahme wären aus meiner Sicht Primärschlüsselfelder bei Datenbanken. Da nimmt man traditionell INT/BIGINT, obwohl damit nie gerechnet wird.

Und zur Ursprungsfrage: Wenn in einem String etwas steht, dass als Zahl umgewandelt werden soll, sind die valueOf/parse-Methoden der Wrapper-Typen zu verwenden. Das willst Du aber nicht, Du willst die hashCode-Methode Deiner Studentenklasse implementieren. Da soll die Matrikelnummer in die Berechnung einfließen, weil sie bei equals() berücksichtigt wird. Nimm dafür die hashCode-Methode. Das ist das Standardvorgehen.

Ich stelle noch mal klar: Ich meinte:

return Integer.parseInt(string);
versus
return string.hashCode();

Meine Vermutung (nicht Standardvorgehensweise): Wenn der String ausschließlich eine Zahl zwischen Integer.MIN_VALUE und Integer.MAX_VALUE enthält, dann ist parseInt eindeutiger und schneller.

Hypothese, nicht bewiesen. :frowning:

Anfänger sollten die Vor- und Nachteile von int, Integer und String (beide) kennen. :slight_smile:

:grr:

Andererseits merkt sich jeder String seinen Hashcode in einem Cache, sodass folgende Aufrufe von hashCode() praktisch kostenlos sind.

Selbst wenn der String ausschließlich eine Zahl enthält, ist doch das Ergebnise von parseInt immer noch ein anderes als das von hashCode, oder nicht?!Oo

Natürlich kommt bei beiden Ergebnissen nicht die gleiche Zahl raus. Aber so wie ich das verstanden habe, ist string das Attribut des Objektes, über das der HashCode ermittelt wird. Und da ist es egal, welche Zahl rauskommt, solange sie für viele Objekte möglichst breit gefächert ist (= viele verschiedene Objekte => Viele verschiedene Zahlen).

Ich würde übrigens IMMER string.hashCode Integer.parse() vorziehen, da zweiteres weniger üblich (= schwerer verständlich) und Fehleranfälliger ist. Was ist, wenn der String ein Buchstaben enthält? Willst du das voher prüfen (=Zusatzaufwand generieren) ?

Und wenn deine Applikation wirklich MERKLICH langsamer läuft, weil string.hashCode() zu langsam ist, dann können wir über Alternativen diskutieren.
Ansonsten ist das hier einfach nur ne Theorie-Diskussion, ob du dein Programm gerne fehleranfällig und 0,1 ms schneller oder robust bauen möchtest. Ich bin da für zweiteres ;). Denn die gesparten Millisekunden hast du beim ersten Fehler alle wieder aufgebraucht.

Die Frage am Anfang so ganz ohne Kontext (zumindest Link?) in den Raum zu werfen ist schon hart. Ich dachte anfangs wirklich, dass gemeint ist obwohl man ernsthaft die hashCode() von String benutzen kann um den int-Wert zu bekommen…

Ich würde auch aufpassen., denn ein Hashcode von einer Zahl (als String) ist nicht gleich der Zahl :wink:

    public static void main(String[] args) {
        int intMartikelNummer = 315889900;
        String stringMatrikelNummer = String.valueOf(intMartikelNummer);
        System.out.println("hashCode: " + stringMatrikelNummer.hashCode());
    }

Natürlich nicht. Aber der hashCode einer Zahl x ist gleich dem hashCode einer Zahl y wenn x=y. Insofern halt auch nicht nützlicher als die Zahl direkt zu nehmen.

Vorsicht mit so einer Aussage, zwei unterschiedliche Zahlen können als String denselben Hashcode haben,

gar nicht so leicht zu finden, aber für „1012“ + „14669600“ gilt dies, Hashcode 1507456

ich war gerade dabei, alle Zahlen zu durchlaufen nach einer, die als Hashcode genau den eigenen Zahlwert hat, leider nicht erfolgreich :wink:

[QUOTE=SlaterB]ich war gerade dabei, alle Zahlen zu durchlaufen nach einer, die den Hashcode genau den Zahlwert hat,
leider nicht erfolgreich ;)[/QUOTE]

:eek:

Genau das hab ich auch gerade gemacht!
Weil das aber so ewig dauert bin ich dazu übergegangen den wissenschaftlich mathematischen Ansatz zu gehen. Ist aber nicht GANZ so einfach, weil dann zB auch mit Character gerechnet wird im Hashcode. -.-

Verwirrend…
Zumindest ist Integer.valueOf("12345").hashCode() == 12345 aber String.valueOf(12345).hashCode() != 12345 und Integer.parseInt("12345") == 12345Hmmm.

Liegt natürlich daran, dass .hashCode() des Value zurückgibt und .hashCode() einen für alle Zeichen errechneten Wert.