Heim  >  Artikel  >  Java  >  Artikel zur Java-Verbesserung ---- Zusammenfassung der Methode equal()

Artikel zur Java-Verbesserung ---- Zusammenfassung der Methode equal()

黄舟
黄舟Original
2017-02-07 16:48:401222Durchsuche

equals()

In der Superklasse Object gibt es diese Methode equal(). Diese Methode wird hauptsächlich verwendet, um zu vergleichen, ob zwei Objekte gleich sind. Der Quellcode dieser Methode lautet wie folgt:

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

Wir wissen, dass alle Objekte eine Identifikation (Speicheradresse) und einen Status (Daten) haben, und „==" vergleicht die Speicheradressen der beiden Objekte. Verwenden Sie also die Methode equal() von Object, um zu vergleichen, ob die Speicheradressen zweier Objekte gleich sind. Das heißt, wenn object1.equals(object2) wahr ist, bedeutet dies, dass equal1 und equal2 tatsächlich auf dasselbe Objekt verweisen. Obwohl die Methode equal() von Object manchmal einige unserer grundlegenden Anforderungen erfüllen kann, müssen wir uns darüber im Klaren sein, dass die Methode equal() von Object derzeit nicht verwendet werden kann Im vorherigen JDK haben Kapselungsklassen wie String und Math die Methode equal() neu geschrieben.

Das Folgende ist die equal()-Methode von String:

public boolean equals(Object anObject) {    if (this == anObject) {        return true;
    }    if (anObject instanceof String) {
        String anotherString = (String)anObject;        
        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;
    }

Für dieses Codesegment: if (v1[i++] != v2[j++]) return false wir können sein sehr klar Beachten Sie, dass die Methode equal() von String einen Inhaltsvergleich und keinen Referenzvergleich durchführt. Andere Kapselungsklassen sind ähnlich.

In der Java-Spezifikation muss die Verwendung der Methode equal() den folgenden Regeln folgen:


Die Methode equal gilt für ein Nicht-Null-Objekt Referenz Verwirklichen Sie die Gleichheitsbeziehung:

1. Reflexivität: Für jeden Referenzwert x ungleich Null sollte x.equals(x) true zurückgeben.

2. Symmetrie: Für alle Nicht-Null-Referenzwerte x und y sollte x.equals(y) genau dann true zurückgeben, wenn y.equals(x) true zurückgibt.

3. Transitivität: Für alle Nicht-Null-Referenzwerte x, y und z gilt: Wenn x.equals(y) true und y.equals(z) true zurückgibt, dann x.equals(z ) Sollte true zurückgeben.

4. Konsistenz: Für alle Nicht-Null-Referenzwerte x und y gibt der mehrmalige Aufruf von x.equals(y) immer true oder immer false zurück, vorausgesetzt, die im Gleichheitsvergleich verwendeten Informationen sind vorhanden Das Objekt wurde nicht überarbeitet.

5. Für jeden Referenzwert x ungleich Null sollte x.equals(null) false zurückgeben.

Für die oben genannten Regeln ist es für uns am besten, sie während der Verwendung einzuhalten, da sonst unerwartete Fehler auftreten.

Um in Java zu vergleichen, müssen wir die entsprechende Vergleichsmethode entsprechend der Art des Vergleichs auswählen:


1) Verwenden Sie im Objektfeld das ist gleich Methode.
2) Typsichere Aufzählung, verwenden Sie equal oder ==.
3) Möglicherweise Nullobjektfelder: Verwenden Sie == und equal.
4) Array-Feld: Verwenden Sie Arrays.equals.
5) Primitive Datentypen außer Float und Double: Verwenden Sie ==.
6) Float-Typ: Verwenden Sie Float.foatToIntBits, um in den Typ int zu konvertieren, und verwenden Sie dann ==.
7) Double-Typ: Verwenden Sie Double.doubleToLongBit, um in einen Long-Typ zu konvertieren, und verwenden Sie dann ==.


Was den Grund betrifft, warum 6) und 7) konvertiert werden müssen, können wir uns auf die equal()-Methode ihrer entsprechenden Kapselungsklassen beziehen die Float-Klasse:

public boolean equals(Object obj) {    return (obj instanceof Float)
           && (floatToIntBits(((Float)obj).value) == floatToIntBits(value));
    }

Der Grund dafür ist, dass zwei Punkte erwähnt werden:

However, there are two exceptions:If f1 and f2 both representFloat.NaN, then the equals method returnstrue, 
even though Float.NaN==Float.NaNhas the value false.If <code>f1 represents +0.0f whilef2 represents -0.0f, or vice
versa, the equal test has the valuefalse, even though 0.0f==-0.0f
has the value true.

Verwenden Sie getClass in equal() zur Typbeurteilung

Wir überschreiben Die Methode equal() Es wird im Allgemeinen empfohlen, getClass anstelle von exampleof für die Typbeurteilung zu verwenden. Wir alle wissen, dass die Funktion von „instanceof“ darin besteht, zu bestimmen, ob das Objekt auf der linken Seite eine Instanz der Klasse auf der rechten Seite ist, und boolesche Daten zurückzugeben. Es kann verwendet werden, um zu bestimmen, ob die Instanz der Unterklasse in der Vererbung die Implementierung der übergeordneten Klasse ist. Beachten Sie den folgenden Satz: Er kann verwendet werden, um festzustellen, ob die Instanz der Unterklasse in der Vererbung die Implementierung der übergeordneten Klasse ist. Dieser Satz verursacht Probleme. Schauen wir uns zunächst das folgende Beispiel an (Auszug aus „High-Quality Code: 151 Suggestions for Improving Java Programs“).

Übergeordnete Klasse: Person

public class Person {    
protected String name;    
public String getName() {        
return name;
    }    
    public void setName(String name) {        
    this.name = name;
    }    
    public Person(String name){        
    this.name = name;
    }    
    public boolean equals(Object object){        
    if(object instanceof Person){
            Person p = (Person) object;            
            if(p.getName() == null || name == null){                
            return false;
            }            
            else{                
            return name.equalsIgnoreCase(p.getName());
            }
        }        
        return false;
    }
}

Unterklasse: Mitarbeiter

public class Employee extends Person{    private int id;
    
    public int getId() {        
    return id;
    }

    public void setId(int id) {        
    this.id = id;
    }

    public Employee(String name,int id){        
    super(name);        
    this.id = id;
    }    
    /**
     * 重写equals()方法
     */
    public boolean equals(Object object){        
    if(object instanceof Employee){            
    Employee e = (Employee) object;            
    return super.equals(object) && e.getId() == id;
        }        
        return false;
    }
}

Sowohl die obige übergeordnete Klasse Person als auch die Unterklasse Employee schreiben gleich() um, aber Employee Es hat ein id-Attribut mehr als die übergeordnete Klasse. Das Testprogramm lautet wie folgt:

public class Test {    public static void main(String[] args) {
        Employee e1 = new Employee("chenssy", 23);
        Employee e2 = new Employee("chenssy", 24);
        Person p1 = new Person("chenssy");
        
        System.out.println(p1.equals(e1));
        System.out.println(p1.equals(e2));
        System.out.println(e1.equals(e2));
    }
}

Das Obige definiert zwei Mitarbeiter und eine normale Person. Obwohl sie denselben Namen haben, handelt es sich definitiv nicht um dieselbe Person, daher sollten die Ausgabeergebnisse logischerweise alle falsch sein , aber es ging nach hinten los. Das Ergebnis ist: wahr, wahr, falsch.


Es ist für uns sehr leicht zu verstehen, dass e1!=e2, weil sie nicht nur Namen, sondern auch IDs vergleichen müssen. Aber p1 ist gleich e1 und e2. Das ist sehr seltsam, weil e1 und e2 offensichtlich zwei verschiedene Klassen sind, aber warum passiert das? Zuerst ruft p1.equals(e1) die Methode „equals“ von p1 auf. Diese Methode verwendet das Schlüsselwort „instanceof“, um zu prüfen, ob es sich bei „e1“ um eine Person-Klasse handelt Auf der rechten Seite können Sie auch feststellen, ob die Instanz der Unterklasse in der Vererbung die Implementierung der übergeordneten Klasse ist. Zwischen ihnen besteht eine Vererbungsbeziehung, sodass sie auf jeden Fall „true“ zurückgeben und ihre Namen gleich sind, sodass das Ergebnis auf jeden Fall wahr ist.


Die obige Situation tritt also auf, weil das Schlüsselwort „instanceof“ verwendet wird, das sehr einfach „auszunutzen“ ist. Daher wird empfohlen, beim Überschreiben von equal getClass zur Typbeurteilung zu verwenden. Verwenden Sie stattdessen „instanceof“.


Das Obige ist die Zusammenfassung des Java-Verbesserungsartikels ----equals() Methode Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www. php.cn)!


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn