==, equals() und Identität und Gleichheit

Aus Byte-Welt Wiki
Zur Navigation springenZur Suche springen

Ohne dass man es angibt oder nicht, erben alle (selbst geschriebenen) Klassen immer implizit von der Klasse java.lang.Object . In Object ist die Methode equals(Object obj) deklariert/definiert:

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

Wie zu sehen ist, überprüft diese Methode auf referenzielle Gleichheit (Identität). Der Wert zweier Variablen ist nur identisch, wenn es sich um ein und dasselbe Objekt handelt (Datentyp: Referenz-Typ), also zwei Variablen auf dasselbe Objekt referenzieren/zeigen.

Oft will man aber den Inhalt von zwei Objekten vergleichen (inhaltliche Gleichheit (= Gleichheit)). Damit ist z. B. die Gleichheit aller Attribute/Objektvariablen von zwei Objekten/Klassen/Variablen gemeint. Deshalb muss die Methode equals() aus Objekt überschrieben werden. Standardmäßig überschreiben auch "alle" Klassen der Java-SE-API diese Methode und geben eine richtige Implementierung / ein richtiges Verhalten vor. Beispiel String:

    public static void main(String[] args) {
        String str1 = "1234";
        String str2 = new String("1234"); // solch ein String-Pool ist zu vermeiden
        System.out.println(str1 == str2);      // Test auf Identität
        System.out.println(str1.equals(str2)); // Test auf Gleichheit

        str1 = str2; //... zeigen auf dasselbe Objekt
        System.out.println(str1 == str2);      // Test auf Identität
        System.out.println(str1.equals(str2)); // Test auf Gleichheit

        str2 = "2341";
        System.out.println(str1 == str2);      // Test auf Identität
        System.out.println(str1.equals(str2)); // Test auf Gleichheit
    }


    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;
    }

Man sollte selber in einer eigenen Klasse equals() z. B. wie folgt überschreiben, wenn die Klasse z. B. 3 Attribute vom Typ int, List und String enthält:

import java.util.ArrayList;
import java.util.List;
  
/**
 * @author
 */
public class Vergleichen {

    private int i = 99;
    private List<String> list = new ArrayList<>(64);
    private String string = "stringList";

    public Vergleichen(int i, String string) {
        //... auf null prüfen,
        // Variablen setzen
        this.i = i;
        this.string = string;
    }

    //... weitere Methoden

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) { //... oder instanceof-Operator
            return false;
        }
        final Vergleichen other = (Vergleichen) obj;
        if (this.i != other.i) {
            return false;
        }
        if ( !this.list.equals(other.list) ) {
            return false;
        }
        if ( !this.string.equals(other.string) ) {
            return false;
        }
        return true;
    }

    public static void main(String[] args) {
    }
}

Hierbei sei ausgeschlossen, dass Attribute der Klasse Vergleichen null sind.

--iKnwWhtUDidLast 22:50, 08. Aug 2013 (CET)