2 Stimmen

Bezüglich des Objektvergleichs

Ich habe eine Java-Klasse Rec. Ich habe zwei Instanzen der Klasse Rec1 und Rec2. Ich möchte prüfen, ob die Werte von Rec1 und Rec2 gleich sind. Wenn ich Rec1.equals(Rec2) ausführe, ist das der richtige Weg, dies zu tun?

class Rec {

  private BigDecimal  RecordId = null; 

  private BigDecimal recSubNum = null; 

  private BigDecimal  FileId = null;

  private String    Category = null; 

  private BigDecimal status = null; 

  private BigDecimal errorCode = null; 

}

3voto

cletus Punkte 596503

Sie müssen die equals() y hashCode() Methoden zur Implementierung der Objektgleichheit in Java:

class Rec {
  private BigDecimal recordId = null;
  private BigDecimal recSubNum = null;
  private BigDecimal FileId = null;
  private String category = null;
  private BigDecimal status = null;
  private BigDecimal errorCode = null;

  @Override
  public int hashCode() {
    int ret = 41;
    ret = hc(ret, recordId);
    ret = hc(ret, recSubNum);
    ret = hc(ret, fieldId);
    ret = hc(ret, category);
    ret = hc(ret, status);
    ret = hc(ret, errorCode);
    return ret;
  }

  @Override
  public boolean equals(Object ob) {
    if (ob == null) return false;
    if (ob.getClass() != Rec.class) return false;
    Rec r = (Rec)ob;
    if (!eq(r.recordId, record)) return false;
    if (!eq(r.recSubNum, recSubNum)) return false;
    if (!eq(r.fileId, fileId)) return false;
    if (!eq(r.category, category)) return false;
    if (!eq(r.status, status)) return false;
    if (!eq(r.errorCode, errorCode)) return false;
    return true;
  }

  private static boolean eq(Object ob1, Object ob2) {
    return ob1 == null ? ob2 == null : ob1.equals(ob2);
  }

  private static int hc(int hc, Object field) {
    return field == null ? hc : 43 + hc * field.hashCode();
  }
}

Anmerkung: der equals/hashCode-Vertrag für Java bedeutet, dass für zwei beliebige Objekte a und b:

a.equals(b) == b.equals(a)

und wenn zwei Objekte gleich sind, dann a.hashCode() muss gleich sein b.hashCode() .

Edita: gibt es zwei Möglichkeiten, um zu prüfen, ob die Typen übereinstimmen. Entweder:

if (ob == null) return false;
if (ob.getClass() != Rec.class) return false;

o

if (!(ob instanceof Rec)) return false;

Diese beiden haben unterschiedliche Aufgaben, und Sie sollten die richtige wählen, je nachdem, was Sie tun wollen. Ich bevorzuge im Allgemeinen die erste Variante, es sei denn, Sie wissen, dass Sie die zweite benötigen. Was ist der Unterschied?

class A {
  public int i;

  public boolean equals(Object ob) {
    if (!(ob instanceof A)) return false;
    return i == ((A)ob).i;
  }
}

Sieht vernünftig aus, oder? Was ist, wenn die Klasse erweitert wird?

class B extends A {
  public int j;

  public boolean equals(Object ob) {
    if (!(ob instanceof B)) return false;
    if (!super.equals(ob)) return false;
    return j == ((B)ob).j;
  }
}

Sieht das immer noch vernünftig aus? Es ist kaputt.

A a = new A();
a.i = 10;
B b = new B();
b.i = 10;
b.j = 20;
System.out.println(a.equals(b)); // true! Is this really what you want?
System.out.println(b.equals(a)); // false! Different to previous = problem.

Deshalb bevorzuge ich getClass() über instanceof es sei denn, ich realmente die Gleichheit der Unterklassen wollen.

0voto

CheesePls Punkte 887

Wenn Rec eine benutzerdefinierte Klasse ist, dann sollten Sie wirklich die equals-Methode überschreiben, sonst wird nur die equals-Methode in der Object-Klasse aufgerufen;

etwas wie:

public boolean equals(Rec x){
    //check here to see if the references are the same, if so return true
    if(this == x) return true;

    //if they aren't the same object then check all the fields for equality
    if (category.equals(x.category) && etc etc) return true;
    else return false;
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X