eine Frage zu hashCode()

Status
Nicht offen für weitere Antworten.

Timo

Mitglied
also ich fange mal von vorne an:

ich habe eine abstrakte Klasse Function, die eine mathematische Funktion x --> f(x) repäsentiert und wollte ihr die methode equals spendieren. nun ist mir aber aufgefallen, dass das nicht ganz einfach ist, da z.b. die beiden funktionen:
f(x) = x^2 * (3x+4) <--ein Produkt
g(x) = 3*x^3 + 4*x^2 <-- eine Summe
gleich sind, also sollte equals auf die beiden funktionen angewendet true ergeben. deswegen hab ich es mir leicht gemacht und definiere es einfach so: Zwei Funktionen sind genau dann gleich, wenn sie in den Funktionswerten an 3 zufällig gewählten Stellen im Intervall [-100;100] übereinstimmen. sollte eigentlich in 99,9% aller Fälle klappen, nur jetzt kommt das Problem mit der Konsistenz von equals() und hashCode(). ich muss ja auch hashCode() überschreiben, sodass 2 Funktionen die laut equals() gleich sind auch den selben hashCode() zurückgeben. hier habe ich es mir wieder einfach gemacht und habe die methode hashCode() einfach folgendermaßen überschrieben:
Code:
public int hashCode(){
    return 1;
}
klappt natürlich, aber jetzt meine frage: wann ist es denn relevant, dass hashCode() "vernünftige" werte zurückgibt?

PS: um die funktionen zu repräsentieren benutze ich übrigens das Composite Pattern (abstrakte Klasse Function mit den methoden getValue(double x) und getDerivate(), dann viele Klassen die von ihr erben, wie z.b. Konstante, Potenzfunktion, Summe, Produkt, Verkettung, etc., aus denen ich dann funktionen zusammensetzen kann.). vielleicht hat ja jmd eine idee wie ich equals() anders realisieren könnte als mit dem "Zufallsverfahren"?
 

Wildcard

Top Contributor
Jede Klasse die Hashs verwendet wird von einer solchen Implemenierung gestört.
Die HashMap zum Beispiel hat nichts anderes mehr zu tun als Kollisionen aufzulösen und wird praktisch unbenutzbar.
 

Ariol

Top Contributor
du könntest die funktion als tree schreiben und diesen dann sortieren lassen (mit der Bedingung, das ein Operator nur Operatoren oder nur Zahlen als Kinder haben darf) Root ist rechts:

Code:
---------------------------------------------
f(x):

(x)\
    (*)\
(x)/     \
            \  
              \         
                \
                 \
                 (*)          
(3)\            /
    (*)\       /
(x)/    \     /
         (+)/
(4)\    /
    (*)/
(1)/

-------------------------------------------------
g(x):

(3)\            
    (*)\       
(x)/    \     
         (*)\
(x)\    /    \
    (*)/       \
(x)/            \
                 (+)
(4)\            /
    (*)\       /
(x)/    \     /
         (*)/
(x)\    /
    (*)/
(1)/

lässt sich umformen zu (ausklammern von x²):

(x)\
    (*)\
(x)/     \
            \  
              \         
                \
                 \
                 (*)          
(3)\            /
    (*)\       /
(x)/    \     /
         (+)/
(4)\    /
    (*)/
(1)/
und das ist wiederum der gleiche tree wie der von f(x). Dieser Tree lässt sich dann auch über equal vergleichen und Hash sollte auch gehen.


Nur eine Idee. ist mir gerade so eingefallen und hab auch keine Idee wie man den Tree implementieren soll bzw. ihn sortieren.

EDIT: codetags gesetzt
 

Timo

Mitglied
danke für den tipp. ich werde mir gedanken drüber machen, dass so zu versuchen zu realisieren :)

ich muss dann wohl jeder klasse die von Function erbt noch ne methode simplify geben, die z.b. distributivgesetz anwendet, terme rauskürzt (wobei hier beachtet werden muss, dass der term nicht null werden kann, wieder ein problem :)) und sachen wie *1 oder +0 entfernt.
 

-frank

Bekanntes Mitglied
deswegen hab ich es mir leicht gemacht und definiere es einfach so: Zwei Funktionen sind genau dann gleich, wenn sie in den Funktionswerten an 3 zufällig gewählten Stellen im Intervall [-100;100] übereinstimmen.

also WENN du es (doch) so einfach machen willst: wähle die werte nicht zufällig. denn ein equals() könnte dann einmal true geben und das nächste mal nicht. nimm immer dieselben werte. dann ist auch hashCode() leicht zu implementieren, denn der hashCode sollte genau von den werten abhängen, die in equals() verglichen werden. du könntest also die 3 in equals() verglichenen werte einfach zusammenzählen und returnen.
 

WieselAc

Top Contributor
wieso definierst du den hashcode nicht einfach als die Summe der Funktionswerte (gerundet) die auch für equals verwendest?

Aber ganz am Rande es gibt unendlich viele Funktionen die an drei oder auch beliebig vielen Stellen den gleichen Funtionswert haben, aber dennoch nicht gleich sind (Auf diesem Prinzip basieren alle numerischen Approximationen).

Um mal zu verdeutlichen, dass es garnicht so unwahrscheinlich ist so etwas zu erhalten:

Durch drei Punkte ist ein Funktion mit mindestens drei unbekannten bestimmt (a*x^2 + b*x + c), also z.B. eine Parabel. Um einfach zu bleiben sind die drei Punkte der Extremwert und die Nullstellen. Dann kannst du durch stauchen und strecken beliebig viel Funktionen erstellen die die gleichen Nullstellen und den gleichen Extremwert besitzten. Soetwas läuft in der Mathematik unter dem Namen "Funktionschar".


Von daher sei vorsichtig wo du das einsetzt!
 

Timo

Mitglied
-frank hat gesagt.:
deswegen hab ich es mir leicht gemacht und definiere es einfach so: Zwei Funktionen sind genau dann gleich, wenn sie in den Funktionswerten an 3 zufällig gewählten Stellen im Intervall [-100;100] übereinstimmen.

also WENN du es (doch) so einfach machen willst: wähle die werte nicht zufällig. denn ein equals() könnte dann einmal true geben und das nächste mal nicht. nimm immer dieselben werte. dann ist auch hashCode() leicht zu implementieren, denn der hashCode sollte genau von den werten abhängen, die in equals() verglichen werden. du könntest also die 3 in equals() verglichenen werte einfach zusammenzählen und returnen.

ja aber wenn ich es so mache, ist es halt zu einfach zwei funktionen zu erstellen, die nicht gleich sind, aber per equals() gleich seien.

z.b. wenn ich die stellen a, b und c betrachte, erstelle ich einfach zwei funktionen:
f(x) = (x-a)(x-b)(x-c)*K
g(x) = (x-a)(x-b)(x-c)*G
mit K != G
f und g schneiden sich nun in den stellen a, b und c, sie wären also laut equals() gleich, obwohl sie sich (je nach K und G) voneinander in allen anderen relevanten Stellen unterscheiden können.

die zufällige wahl sorgt dafür, dass die wahrscheinlichkeit, dass mal zwei ungleiche funktionen als gleich gelten, nahezu 0 ist.
 

Leroy42

Top Contributor
Timo hat gesagt.:
die zufällige wahl sorgt dafür, dass die wahrscheinlichkeit, dass mal zwei ungleiche funktionen als gleich gelten, nahezu 0 ist.

Na bravo!

Wenn diese Wahrscheinlichkeit gleich p (z.B. 99.99%) ist kannst du
sie dann leicht auf 1-(1-p)² (99,999999%) steigern, wenn du schreibst

Code:
if (a.equals(b) && b.equals(a))

:cool:

(aber mach dann deinen Code ja niemanden zugänglich)
 

Lim_Dul

Top Contributor
Ob zufällig oder fest gewählt hat auf die Wahrscheinlichkeit erstmal keinen großen Einfluß. Dafür müsste man zusätzlich wissen, um was für Funktionen es sich handelt.

Die zufällige Wahl hat aber einen Nachteil, sie ist nicht stabil. Und es sobald du Listen zum abspeichern nutzt, indexOf, contains aufrufst, kannst du mit Bugs konfrontiert werden, die sich letztendlich darauf zurückführen lassen, aber derartig selten und versteckt sind, dass man sie nie wirklich erkennt.

Und das Argument, dass man bei fester Wahl, leicht zwei Funktionen erstellen kann, die equal sind, aber nicht gleich sind, zieht auch nicht. Dafür müsste jemand böswillig sein. Wenn die Funktionen zufällig sind, dann ist eine feste Wahl genausogut wie eine zufällige.


Mein persönlicher Vorschlag wäre, im Konstruktor der Funktion drei Zufallszahlen zu definieren und die dann in equals immer als Testzahlen zu nehmen. Dadurch hast die Garantie, dass equals stabil ist und dennoch die Zufallskomponente drin.
 

Ariol

Top Contributor
noch eine Idee: über Postfix-screibweise auflösen:

f(x) = xx*3x*4+*
g(x) = 3xxx***4xx**+

dann von hinten suchen ob ein man ein +*, -*, +/ oder -/ findet und das ganze dann dementsprechend ändern (also die 2 davorstehenden Zahlengruppen(samt Operatoren) mit dem 3 davorstehenden Wert(samt Operatoren) verknüpfen (* oder / dranhängen) und den anderen Operator (+ oder -) hinten anhängen)

Also: (g(x) ist schon korrekt)

f(x) = xx*3x*4+*

+* gefunden

3x und 4 um xx* erweitern:

3xxx***4xx**+

und das ist gleich g(x)

musst halt noch + und - und * und / aufeinander abstimmen also, dass xxx*/ = x wird

ist vermutlich nicht so einfach wie das mit den Zufallszahlen, aber wenn du es richtig implementierst ist die erfolgsrate 100%
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
KonradN Mal eine Frage zu Binary Serialization Allgemeine Java-Themen 15
T Eine Frage des Designs Allgemeine Java-Themen 2
J Eine Frage zu den Threads und Task Allgemeine Java-Themen 1
S Noch eine Design-Frage zu Setter Allgemeine Java-Themen 6
C Eine Frage zur Bearbeitungszeit Allgemeine Java-Themen 8
A eine test thread.join() frage Allgemeine Java-Themen 2
A Noch eine Frage zur Methode matches() Allgemeine Java-Themen 2
J Java-Datei unter Mac OS X öffnen - eine Frage der Klasse Allgemeine Java-Themen 2
M Eine Frage über Unit-Tests mit Java Allgemeine Java-Themen 2
M Nur mal eine kurze Frage zum FileOutPutStream Allgemeine Java-Themen 6
R Eine Frage zum Streaming - EDIT Allgemeine Java-Themen 2
F Gutes Threads Tutorial hier aber trotzdem eine Frage Allgemeine Java-Themen 7
G Eine Frage zu Java Allgemeine Java-Themen 15
D Hat Java eine Library um JavaScript auszuwerten? Allgemeine Java-Themen 2
dokan wie kann ich eine funktionierende Suchleiste erstellen Allgemeine Java-Themen 1
B Wie erstelle ich dazu eine Abfrage ob der Button gedrückt wurde? Allgemeine Java-Themen 8
J Integration pay Pale in eine JavaFx Desktop Application Allgemeine Java-Themen 1
berserkerdq2 Wenn ich einfach eine GIF in den Scenebuilder als Bild reinpacke, wird das dann asl Gif angezeigt Allgemeine Java-Themen 1
8u3631984 Strukturiertes Logging : Jedes Feld in eine seperate Zeile - aber wie ? Allgemeine Java-Themen 2
berserkerdq2 Gibt es eine saubere Dokumentation von Jfoenix? Allgemeine Java-Themen 1
M Eigene Datenstruktur um eine Menge zu speichern Allgemeine Java-Themen 3
A Wie schreibe ich eine For-Schleife in ein Stream API um? Allgemeine Java-Themen 12
E Es ist nicht möglich, eine Batch-Anweisung auszuführen. Allgemeine Java-Themen 9
R Best Practice Erfahrungswerte für eine Migration von JSF nach Angular (oder anderes JS-Framework) Allgemeine Java-Themen 1
H Eine Linie verkürzen Allgemeine Java-Themen 5
N rekursion mehrfach eine Methode Öffnen Allgemeine Java-Themen 4
berserkerdq2 Wenn ich eine Methode nur jede 50ms ausführen will, wie mach ich das? Allgemeine Java-Themen 4
berserkerdq2 Wie synchronisiere ich eine for-Schleife Allgemeine Java-Themen 12
berserkerdq2 Wie mache ich in IJVM eine if verzweigung? Allgemeine Java-Themen 27
F Gibt es mittlerweile eine Alternative zu DaisyDiff Allgemeine Java-Themen 2
_user_q Was brauche ich, um eine eigene "Search for updates"-Funktion einzubauen? Allgemeine Java-Themen 1
E Eine Methode einer extendeten Klasse deakitivieren Allgemeine Java-Themen 12
LimDul Kam eine java.net.URL zu einer HashMap und ging als DNS Anfrage wieder heraus Allgemeine Java-Themen 18
pizza_dox_9999 Wie füge ich eine "eigene" ScriptEngine dem ScriptEngineManager? Allgemeine Java-Themen 3
F Kennt ihr eine Library um 2 HTML Seiten zu diffen? Allgemeine Java-Themen 8
Y ImagePanel von anderer Klasse in eine MainFrame Klasse hinzufügen. Allgemeine Java-Themen 1
OnDemand Anzeigen was eine Applikation macht Allgemeine Java-Themen 1
T Problem beim Umwandeln in eine Jar-Datei Allgemeine Java-Themen 3
Tobero Wie bekomme ich in welchem Quadrat sich eine Position in einem Grid befindet Allgemeine Java-Themen 11
Tobero Wie kann man eine Poisson Disc Sampler? Allgemeine Java-Themen 7
M Openjdk - gibt es auch eine Openjre? Allgemeine Java-Themen 7
R Lambda Expression in einer Methode execute() aufrufen (execute() ist eine Methode aus dem funktionalen Interface Command) Allgemeine Java-Themen 5
N Arrayliste in eine Datei speichern Allgemeine Java-Themen 4
J Öffnen eine jar-Datei Allgemeine Java-Themen 11
Zrebna Gibt es eine Möglichkeit eine NPE zu vermeiden, wenn null returned wird? Allgemeine Java-Themen 3
S Klassen Einfügen von unbekannter menge an Variablen in eine Klasse mithilfe von ASM Allgemeine Java-Themen 5
R Wo müsste ich im Code eine Änderung vornehmen? Allgemeine Java-Themen 6
S Rückgabe einer HttpURLConnection für eine Seite einlesen bei der man eingeloggt ist..? Allgemeine Java-Themen 5
S Gibt es eine Moeglichkeit die Runtime Ausführung zu analysieren..? Allgemeine Java-Themen 7
S Habt ihr eine Idee wie man Serializierung testen kann..? Allgemeine Java-Themen 6
S Wenn eine Klasse zwei Interfaces mit derselben Methodensignatur implementiert: welche wird aufgerufen? Allgemeine Java-Themen 15
Drachenbauer warum bekomme ich hier eine NullPointerException Allgemeine Java-Themen 6
M Gibt es eine API die den aktuellen Wert eines Indikators beim Trading zurückgibt? Allgemeine Java-Themen 7
X Collections Gibt es eine Klasse welche die Vorteile von List und HashMap vereint, aber konstante Laufzeit (O(1)) hat in Java? Allgemeine Java-Themen 4
N Eine stelle der Fibonacci-Zahlenfolge ausgeben. Allgemeine Java-Themen 4
E Hat der Compiler einen Fehler oder warumbeendet return nicht eine Methode ? Allgemeine Java-Themen 7
W Collections Suche etwas Sorted-List-Artiges...hat jemand eine Idee? Allgemeine Java-Themen 13
L Methoden Über Reflections eine Methode mit aufrufen Allgemeine Java-Themen 3
S Kann ich eine Methode schreiben die alle Arten von funktionalen Interfaces akzeptiert..? Allgemeine Java-Themen 21
Drachenbauer Wie kann eine vorgegebene Farbe über einen String erkannt werden? Allgemeine Java-Themen 11
J Datenstruktur für eine Map erstellen Allgemeine Java-Themen 2
sascha-sphw Java 9 module Zugriff auf eine resource einer anderen JAR Allgemeine Java-Themen 0
pkm Kann eine ServerSocket-Klasse nicht stateful sein? Allgemeine Java-Themen 4
B Aufruf der Methode ergibt eine Exception Allgemeine Java-Themen 13
I Eine Anwendung so gut wie möglich beschützen Allgemeine Java-Themen 9
M Wie kann man eine void Methode mit Variablen von zwei verschiedenen Objekten ausführen? Allgemeine Java-Themen 15
X Wie mache ich hier eine Rekursion rein ? Allgemeine Java-Themen 7
K OOP Suche Hilfe + Erklärung für eine Hausaufgabe Allgemeine Java-Themen 1
N Über einen Button in JavaFX ein Event über eine Pipeline schicken(Netty) Allgemeine Java-Themen 1
M Login in eine Webseite mit Java Allgemeine Java-Themen 3
A NetBeans Suche Programmierer für eine Belegarbeit Allgemeine Java-Themen 11
D Warum kann ich eine (deflaut) Klasse aus einer Libary in einem anderen Projekt benutzen? Allgemeine Java-Themen 3
L Übergabe an eine eher einfache Java- Applikation wegen Kündigung Allgemeine Java-Themen 1
C Ein Iterator ist eine Implementierung des Interface Iterable? Allgemeine Java-Themen 2
M Schlüsselworte Was ist eine Java Spezifikation + JSR? Allgemeine Java-Themen 11
E RMI NULL-Pointer-Exeception wenn der RMI-Proxy eine Methode deligiert Allgemeine Java-Themen 2
E RMI FWH: RMI- Wie erstelle ich stubs dynamisch, bzw. unterdrücke eine Statisch-Warnung? Allgemeine Java-Themen 0
J Eine bestimmte Zahl im Integer ändern Allgemeine Java-Themen 9
Q-bert Strings aus der JList in eine Datenbank speichern Allgemeine Java-Themen 1
D Möglichkeit mit GAE eine Table auszulesen und eine csv zu schreiben Allgemeine Java-Themen 22
S Korrekte Pfadangaben damit eine .jar Datei unter Windwos läuft. Allgemeine Java-Themen 24
D Eine Forschleife mit Threads abarbeiten um es zu schneller zu machen. Ist das möglich? Allgemeine Java-Themen 20
S Wie kann ich eine kleine Stelle in meinem Code mit multiplen Threads abarbeiten..? Allgemeine Java-Themen 20
B Gibt es eine Funktion die den Datentyp einer Variablen ermittelt? Allgemeine Java-Themen 8
R bei eclipse von java in eine andere programmiersprache wechseln? Allgemeine Java-Themen 2
D Pivot-Wahl beim QuickSort steigert die Effizienz, eine Lüge??? Allgemeine Java-Themen 17
C Eclipse einstellen, dass eine bestimmte JDK benutzt werden soll Allgemeine Java-Themen 3
M Klassen Eine Klasse in mehreren Klassen einbinden Allgemeine Java-Themen 11
A Best Practice Java - eine Art Plugin-Struktur Allgemeine Java-Themen 3
S wie rufe ich mit .jar datei eine .bat auf? Allgemeine Java-Themen 15
R Signatur von Methoden in eine Datei schreiben? Allgemeine Java-Themen 4
perlenfischer1984 Functionsparameter prüfen und eine Exception werfen !? Allgemeine Java-Themen 11
J Mehrere Wörter getrennt in eine Array einlesen, wie ? Allgemeine Java-Themen 7
E Methoden Hat jemand eine gute Lösung? Allgemeine Java-Themen 5
Z NullPointerException beim Schreiben einer ArrayList in eine Datei Allgemeine Java-Themen 6
Exdroid BlueJ Wie bekomme ich die Ausgabe in eine TXT Datei? Allgemeine Java-Themen 2
G Methoden Aus einem Event, wo ich weiß, dass es ausgeführt werden wird, eine Get-Methode basteln Allgemeine Java-Themen 8
F Wie kann ich auf einem System prüfen, ob eine lib verfügbar ist? Allgemeine Java-Themen 2
Tausendsassa Interface Eine Gui von einer anderen schließen lassen Allgemeine Java-Themen 3
S Threads Kann mir jemand helfen eine parallele Hilfsklasse zu implementieren..? Allgemeine Java-Themen 3

Ähnliche Java Themen

Neue Themen


Oben