2016-06-03 23 views
2

Meine Klasse:Java "enthält" nicht ordnungsgemäß funktioniert

public class UserProgressModel { 

    private String email; 

    public UserProgressModel(String pEmail) { 
     super(); 

     this.email = pEmail; 
    } 

    @Override 
    public boolean equals(Object x) { 

     if (x != null && x instanceof UserProgressModel 
       && ((UserProgressModel) x).email.equals(this.email) == true) { 

      return true; 
     } 

     if (x != null && x instanceof String 
       && x.equals(this.email) == true) { 

      return true; 
     } 

     return false; 
    } 

    @Override 
    public int hashCode() { 
     int hash = 7; 
     hash = 17 * hash + (this.email != null ? this.email.hashCode() : 0); 
     return hash; 
    } 
} 

Und nachdem einige Objekte über Gson setzen:

UserProgressModel[] userProgressArray; 
List<UserProgressModel> retUserProgress = new ArrayList<>(); 

userProgressArray = gs.fromJson(fileContents, 
         new TypeToken<UserProgressModel[]>() { 
         }.getType()); 

for (UserProgressModel ele : userProgressArray) { 

    if (ele != null) { 
     retUserProgress.add(ele); 
    } 
} 

vermag ich nicht für den folgenden Code um wahr zu bekommen:

retUserProgress.contains("[email protected]"); 

Ich durch das Array geloopt, um zu überprüfen, ob ein Objekt die E-Mail hat.

Mache ich richtig? Ich denke, ich habe die Gleichen & Hashcode überschrieben.

+0

Wenn Sie 'UserProgressModel.equals (...)' Ihnen sagen, dass das Objekt einem 'String' entspricht, entspricht dies nicht dem allgemeinen Vertrag der 'equals'-Methode. Ein 'UserProgressModel' ist nicht wirklich" gleich "einer Zeichenkette. Darüber hinaus gibt 'myString.equals (myUserProgressModel)' immer false zurück, sodass Sie eine asymmetrische Gleichheit erstellen. Außerdem haben Ihre Zeichenfolge und Ihre Modellinstanz unterschiedliche Hash-Codes, daher sollten sie nicht so aussehen, als wären sie gleich. – khelwood

+0

retUserProgress ist eine Liste ... Nicht direkt UserProgressModel, also vielleicht ist das ein Problem. – Hrabosch

Antwort

0

Sie können nicht überprüfen, ob das retUserProgress E-Mails enthält, weil dies nicht der Fall ist. Die ArrayList enthält Objekte der Klasse: UserProgressModel, damit Sie überprüfen können, ob die ArrayList ein 'UserProgressModel' enthält.

Was möchten Sie tun mag, ist die folgende

private boolean containsEmail(List<UserProgressModel> retUserProgress, String email) { 
    boolean result = false; 

    for (UserProgressModel object : retUserProgress) { 
     if (object.equals(email)) 
      result = true; 
    } 

    return result; 
} 

Und der Aufruf der Methode, wie so:

containsEmail(retUserProgress, "[email protected]"); //This will return a true or false, depending if the ArrayList retUserProgress contains the email 
-2

i Code getestet haben in ideone

und es funktioniert

true

UserProgressModel model=new UserProgressModel("[email protected]"); 
System.out.print(model.equals("[email protected]")); 

false

UserProgressModel model=new UserProgressModel("[email protected]"); 
System.out.print(model.equals("[email protected]")); 

Versuch mit neuem Objekt

retUserProgress.contains(new UserProgressModel("[email protected]")) 

result

zu vergleichen, wenn Sie wollen nicht mit einem neuen UserProgressModel Sie Ihre eigene Liste müssen vergleichen, um erstellen Geben Sie an, dass beim Vergleich zweier Objekte (UserProgressModel, string) ein neues UserProgressModel erstellt und übergeben wird E-Mail dafür

5

Ihre equals-Implementierung ist falsch. Wenn man sich den Vertrag aussehen gleich für die Umsetzung symmetrisch sein muss:

... for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true. 

In Ihrem Fall, dass Sie eine Liste der UserProgressModel Objekte haben, aber Sie versuchen, gegen einen String zu vergleichen. Während Sie UserProgressModel.equals (String) implementiert haben, müssen Sie String.equals (UserProgressModel) immer noch das richtige Ergebnis zurückgeben. Da dies nicht möglich ist, wird diese Implementierung niemals in allen Fällen funktionieren. Was Sie tun sollten, ist zwei Dinge:

Entfernen Sie den Check-in gleich für String, weil es nie funktioniert.

ein Mock-Objekt Verwenden Sie in der Sammlung zu überprüfen:

retUserProgress.contains(new UserProgressModel("[email protected]")); 

Solange Ihre Methode equals in den eigenen Typ (UserProgressModel korrekt ist.gleich (UserProgressModel)) sollte dies Ihr Problem beheben.

Verwandte Themen