Java equal() und hashcode()

In diesem Tutorial werden die Methoden equal() und hashcode() in einfachen Worten erklärt. Dies ist eine der verwirrenden Fragen, die Java-Entwicklern beschäftigen. Die häufigsten Fragen zu diesen Methoden sind:

  • Was ist die Methode equal() und warum sollte ich sie in unseren Klassen überschreiben?
  • Was ist die hashcode()-Methode?
  • Warum sollte ich hashcode() immer überschreiben, wenn ich die Methode equal() überschreibe?
  • Lesen Sie auch:

    • HashCode- und Equals-Methoden
    • Datei asynchron in Java lesen

    gleich()

    Ich gehe davon aus, dass Sie möglicherweise bereits die Grundlagen von Objekten und Strings in Java kennen. Möglicherweise stoßen Sie auf mehrere Situationen, in denen Sie möglicherweise vergleichen müssen, ob zwei Dinge gleich sind. Zu diesem Zweck stellt Java die Methode equal() bereit, die vergleicht, ob zwei Objekte gleich sind(Lesen : Vergleichbare vs. Komparatorschnittstelle in Java ).

    Nehmen Sie dieses einfache Beispiel:

    public class StrEquals {
    
           public static void main(String() args) {
    
                 Object obj1 = new Object();
                 Object obj2 = new Object();
    
                 System.out.println(obj1.equals(obj2));
    
                 obj1 = obj2;
    
                 System.out.println(obj1.equals(obj2));
          }
    }
    

    Der Code macht nichts Besonderes, außer dass er die Methode equal() zum Vergleichen zweier Objekte verwendet. Die erste print-Anweisung gibt „false“ aus, da die beiden erstellten Objekte unterschiedlich sind. Unter dieser Druckanweisung habe ich jedoch ein Objekt einem anderen zugewiesen, sodass beide Objekte auf denselben Speicherort verweisen. Daher gibt die Methode equal() beim Aufruf im zweiten Fall true zurück.

    Dies ist die Open-Source-Implementierung der Methode equal() von Java Object.

    public boolean equals(Object obj) {
        return (this == obj);
    }
    

    Kann ich diese Objekt-equals()-Methode für alle meine Klassen verwenden? Wird es funktionieren? Die Antwort lautet in den meisten Fällen NEIN. Sehen wir uns das anhand eines Beispiels an.

    public static void main(String() args) {
    
            String str1 = "test";
            String str2 = "test";
    
            System.out.println(str1.equals(str2));
    
     }
    

    Das Ziel besteht darin, zu vergleichen, ob zwei String-Inhalte gleich sind, und nicht darin, zwei String-Objekte zu vergleichen. Ohne weiter zu lesen, halten Sie inne und überlegen Sie einen Moment, ob die Standardobjektimplementierung von equal() bei Strings? funktioniert. Ich hoffe, Sie haben darüber nachgedacht. Sie hätten gedacht, dass die Standardmethode Object equal() nicht funktionieren wird. Also, was machen wir?.

    Jetzt kommen wir zum Überschreiben der Methode equal(). Da unser Ziel darin besteht, die Gleichheit zweier String-Inhalte zu vergleichen und nicht die beiden String-Objekte, sollten wir als Programmierer diese Methode equal() überschreiben und unsere eigene Implementierung bereitstellen.

    Der Java-Open-Source-Code der String-equals()-Methode sieht folgendermaßen aus.

    public boolean equals(Object strObject) {
    
            if (this == strObject) {
                   return true;
            }
    
            if (strObject instanceof String) {
                   String anotherString = (String) strObject;
                   int n = count;
                   if (n == anotherString.count) {
                         char v1() = value;
                         char v2() = anotherString.value;
                         int i = offset;
                         int j = anotherString.offset;
    
                         while (n-- != 0) {
                              if (v1(i++) != v2(j++))
                                   return false;
                         }
                         return true;
                   }
            }
    
            return false;
    }
    

    Versuchen Sie nicht, den obigen Code zu verstehen. Dies dient lediglich der Veranschaulichung der Tatsache, dass die Die standardmäßige Objektimplementierung der Methode „equals()“ erfüllt hier nicht unseren Zweck und muss daher die Methode „equals()“ in unseren Klassen überschreiben und eine Implementierung gemäß den Anforderungen bereitstellen. Ich hoffe, das macht deutlich, dass die Methode equal() überschrieben werden muss.

    Notiz: Eine Sache, die Sie im Hinterkopf behalten sollten, ist Folgendes: Wenn Sie in Ihrer Klasse keine Methode equal() angeben, verwendet Java die Standardmethode equal() in der Object-Klasse, da alle Objekte von der übergeordneten Object-Klasse abgeleitet werden.

    Ich hoffe, dass Sie auch neugierig auf hashcode() sind.

    Hash-Code()

    Die Methode Hashcode() macht nichts Besonderes, sondern gibt den Hash-Codewert für das Objekt zurück. Wenn Sie noch nie von Hashcode gehört haben, denken Sie, dass diese Methode unterschiedliche Ganzzahlen für unterschiedliche Objekte zurückgeben würde.

    Kommen wir nun zur wichtigsten Frage: Warum ist es immer ratsam, hashcode() zu überschreiben, wenn die Methode equal() überschrieben wird? Java hat in seinen JavaDocs einen Vertrag, der besagt, dass, wenn zwei Objekte gemäß equal(Object) gleich sind, der Aufruf der hashcode()-Methode für diese Objekte auch das gleiche ganzzahlige Ergebnis liefern muss. Mit anderen Worten: Wenn object1.equals(object2) wahr ist, muss auch object1.hashcode() == object2.hashcode() gleich sein. Genug der Theorie, kommen wir zu einem Beispiel.

    public class StrEquals {
    
         private int str1;
    
         StrEquals(int s1){
              str1 = s1;
         }
    
         public static void main(String() args) {
              StrEquals equals = new StrEquals(10);
              StrEquals equals1 = new StrEquals(20);
              StrEquals equals2= new StrEquals(30);
    
              HashSet< StrEquals> map1 = new HashSet<StrEquals>();
              map1.add(equals);
              map1.add(equals1);
              map1.add(equals2);
    
              System.out.println(map1.contains(new StrEquals(10)));
    
         }
    
         @Override
         public boolean equals(Object obj) {
              StrEquals equals = (StrEquals) obj;
              if (this.str1 == equals.str1){
                   return true;
              }
              else
                   return false;
         }
    }
    

    Was wird die print-Anweisung ausgeben? FALSCH!! Warum?

    Denn wenn wir die Methode equal() überschreiben, überschreiben wir die allgemeinen Bedingungen, die für die Gleichheit von Objekten verwendet werden, mit unserer eigenen benutzerdefinierten Logik. Wenn wir also einige Methoden wie „contains“ aufrufen, wie in diesem Fall Java intern sowohl die Methode hashcode() als auch equal() verwendet, führt dies zu einigen Fehlern, die schwer zu verfolgen sind. Außerdem haben wir den Vertrag gebrochen, der besagt, dass, wenn zwei Objekte() mit equal() gleich sind, auch ihre Hash-Codes gleich sein müssen.

    Obwohl wir in unserem Fall die gleiche neue StrEquals(10)-Methode in der Methode „contains“ aufrufen, erhält sie zwei unterschiedliche Hashwerte, da Java sie als unterschiedliche Objekte betrachtet. Es ist unsere Pflicht, Java zu sagen, dass diese ein und dasselbe sind, indem wir unsere eigene überschriebene Methode hashcode() in unseren Klassen verwenden.

    Zusammenfassung

    Um diese Art von nicht auffindbaren Fehlern zu vermeiden und den Java-Vertrag einzuhalten, überschreiben wir IMMER die Methode hashcode(), wenn wir die Methode equal() überschreiben. Ich hoffe, es hat Ihnen Spaß gemacht, meine Gedanken zum Überschreiben von equal() und hashcode() zu lesen. Bitte posten Sie Ihre Kommentare/Korrekturen, falls vorhanden. Danke fürs Lesen.

    Dieser Artikel wurde ursprünglich unter veröffentlicht Java-Tutorials – Lasst uns ins Meer springenhier mit Genehmigung des Autors und als Teil des JBC-Programms erneut veröffentlicht.

    Kommentar verfassen

    Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

    Nach oben scrollen