2017-06-01 7 views
3

Angenommen, ich habe eine generische Container-Typ wie folgt aus:Wie implementiere ich Equals für generische Typen?

public final class Container<T> { 

    public final T t; 

    public Container(final T t) { 
     this.t = t; 
    } 
} 

ich so implementieren möchten gleich, dass dies passiert:

final Container<Object> a = new Container<>("Hello"); 
final Container<String> b = new Container<>("Hello"); 

assertNotEquals(a, b); 

Die Instanzen a und b anders sein sollte, weil ihre Art Parameter T ist anders.

Aufgrund der Löschung ist dies jedoch schwierig zu tun. Diese Implementierung, zum Beispiel, ist falsch:

@Override 
public boolean equals(final Object obj) { 
    if (this == obj) { 
     return true; 
    } 
    if (obj != null && obj instanceof Container<?>) { 
     final Container<?> other = (Container<?>)obj; 
     return Objects.equals(this.t, other.t); 
    } 
    return false; 
} 

Ich erwarte, dass ich eine Art von Token für T speichern müssen.

Wie implementiere ich Equals für generische Typen?


This beantwortet die Frage nicht.

+1

Es hat wirklich nichts zu tun w ie Löschung. Wenn Sie Arrays verwenden, wo kein Löschen möglich ist, wie 'Object [] a = {" Hello "}; String [] b = {"Hallo"}; ',' a [0] .equals (b [0]) 'würde immer noch' true' zurückgeben. Die Operation 'equals' verwendet die Laufzeittypen des Objekts. – RealSkeptic

Antwort

3

Sie können ein wenig die Container-Klasse ändern und dieses Feld hinzufügen:

public final Class<T> ct; 

mit, dass und das Gleichheits außer Kraft setzen dann

System.out.println(a.equals(b)); 

wird false zurück, weil die Methode equals Class<String> vs Class<Object> prüfen wird

class Container<T> { 

    public final T t; 
    public final Class<T> ct; 

    public Container(final T t, Class<T> ct) { 
     this.t = t; 
     this.ct = ct; 
    } 

    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = (prime * result) + ((ct == null) ? 0 : ct.hashCode()); 
     result = (prime * result) + ((t == null) ? 0 : t.hashCode()); 
     return result; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     Container other = (Container) obj; 
     if (ct == null) { 
      if (other.ct != null) 
       return false; 
     } else if (!ct.equals(other.ct)) 
      return false; 
     if (t == null) { 
      if (other.t != null) 
       return false; 
     } else if (!t.equals(other.t)) 
      return false; 
     return true; 
    } 

} 
+0

Gibt es eine Möglichkeit, die Kesselplatte des neuen Containers ("a", String.class) zu entfernen? Funktioniert das noch für 'Container >'? – sdgfsdh

+1

Sie sollten sich mit 'Objects.hash()' vertraut machen, was genau das tut, was Ihre Implementierung von 'hashCode()' tut, also wird Ihre Methode nur 'return Objects.hash (ct, t);' – Bohemian

Verwandte Themen