2012-08-19 95 views
1

如何抓在下面的代碼對象數組的唯一列表:抓取對象數組的唯一列表

import java.util.*; 

    class t1 { 
     public static void main(String[] args) { 

      Object[] o1 = new Object[] { null, "[email protected]", "ENG", "775778435", 1}; 
      Object[] o2 = new Object[] { null, "[email protected]", "ENG", "775778435", 1}; 

      List<Object[]> result = new ArrayList<Object[]>(); 
      result.add(o1); 
      result.add(o2); 

      // The above result list is coming from some DB & I cannot change the structure of above script. 
      // Now, I need to remove the duplicates from this result list meaning I need to find duplicates from the objects within the list. 
      // I tried below code but it still prints duplicates. Any help??? 

      Set<User> setResult = new HashSet<User>(); 
      User userInfo = null; 

      for (Object[] userData : result) { 
       userInfo = new User((String)userData[0], (String)userData[1], (String)userData[2], (String)userData[3], (Integer) userData[4]); 
       setResult.add(userInfo); 
      } 

      Iterator it = setResult.iterator(); 
      while (it.hasNext()) { 
       Object o = it.next(); 

       User u = (User) o; 
       System.out.println("non-duplicate = " + u.getEmail()); 
      } 

      // Expected result: non-duplicate = [email protected] 
      // Actual result: non-duplicate = [email protected] getting printed twice i.e. duplicate not getting removed! 
     } 
    } 

    class User { 
     public String firstName; 
     public String email; 
     public String language; 
     public String productCode; 
     public int status; 

     public User() {   
     } 

     public User(String fName, String userId, String lang, String productCode, int status) { 
      this.firstName = fName; 
      this.email = userId; 
      this.language = lang; 
      this.productCode = productCode; 
      this.status = status; 
     } 

     public String getFirstName() { 
      return firstName; 
     } 

     public void setFirstName(String firstName) { 
      this.firstName = firstName; 
     } 

     public String getEmail() { 
      return email; 
     } 

     public void setEmail(String email) { 
      this.email = email; 
     } 

     public String getLanguage() { 
      return language; 
     } 

     public void setLanguage(String language) { 
      this.language = language; 
     } 

     public String getProductCode() { 
      return productCode; 
     } 

     public void setProductCode(String productCode) { 
      this.productCode = productCode; 
     } 

     public int getStatus() { 
      return status; 
     } 

     public void setStatus(int status) { 
      this.status = status; 
     } 

     @Override 
     public int hashCode() { 
      int fNameHash = 0; 
      int lNameHash = 0; 
      int emailHash = 0; 
      int langHash = 0; 
      int productCodeHash = 0; 

      if (this.firstName != null) { 
       fNameHash = this.firstName.hashCode(); 
      } 

      if (this.email != null) { 
       emailHash = this.email.hashCode(); 
      } 

      if (this.language != null) { 
       langHash = this.language.hashCode(); 
      } 

      if (this.productCode != null) { 
       productCodeHash = this.productCode.hashCode(); 
      } 

      return (fNameHash + lNameHash + emailHash + langHash + productCodeHash + this.status); 
     } 

     @Override 
     public boolean equals(Object obj) { 
      if(obj != null && obj instanceof User) { 
       User temp = (User) obj; 

       if (this.firstName != null && temp.firstName != null && this.firstName.equalsIgnoreCase(temp.firstName) 
        && this.email != null && temp.email != null && this.email.equalsIgnoreCase(temp.email) 
        && this.language != null && temp.language != null && this.language.equalsIgnoreCase(temp.language) 
        && this.productCode != null && temp.productCode != null && this.productCode.equalsIgnoreCase(temp.productCode) 
        && this.status == temp.status) {    
        return true; 
       } 
      } 
      return false; 
     } 
    } 

我預期的結果是打印[email protected]只有一次,但其得到印刷兩次!

任何人都可以告訴我如何更正此代碼嗎?

謝謝!

回答

0

問題是兩個對象的firstName值爲null。因此,equals()方法返回false,並且您的對象被Set認爲是不同的。

試着改變你的equals和hashCode下列要求:

@Override 
public boolean equals(Object o) { 
    if (this == o) return true; 
    if (!(o instanceof User)) return false; 

    User user = (User) o; 

    if (status != user.status) return false; 
    if (email != null ? !email.equals(user.email) : user.email != null) return false; 
    if (firstName != null ? !firstName.equals(user.firstName) : user.firstName != null) return false; 
    if (language != null ? !language.equals(user.language) : user.language != null) return false; 
    if (productCode != null ? !productCode.equals(user.productCode) : user.productCode != null) return false; 

    return true; 
} 

@Override 
public int hashCode() { 
    int result = firstName != null ? firstName.hashCode() : 0; 
    result = 31 * result + (email != null ? email.hashCode() : 0); 
    result = 31 * result + (language != null ? language.hashCode() : 0); 
    result = 31 * result + (productCode != null ? productCode.hashCode() : 0); 
    result = 31 * result + status; 
    return result; 
} 

最好的辦法是從您的IDE生成equals和hashCode作爲另一個答案建議。

+0

名稱可以爲空,這就是要求。我如何解決它? – Mike 2012-08-19 23:34:39

+0

如果我在equals方法中刪除了fName的空檢查,它會給出空指針異常....那麼我該怎麼做呢? – Mike 2012-08-19 23:40:47

2

的問題是,你的User.equals將可預見的退回false,因爲這兩種情況下有nullfirstName S:

if (this.firstName != null && temp.firstName != null && this.firstName.equalsIgnoreCase(temp.firstName) 

結果,即使它們具有相同的hashCode,它僅僅作爲一個碰撞處理而不是匹配,因爲equals已損壞。

嘗試糾正:-)的東西,如更換邏輯...

firstName == temp.firstName || firstName != null && firstName.equalsIgnoreCase(temp.firstName) 

...應該工作;-)

你可以看到一個完全正常的工作版本here


順便說一句,你忘了曾經分配lNameHashUser.hashCode

+0

你能幫我糾正它嗎?你能否給我提供示例代碼?如果我在equals方法中刪除了對fName的空檢查,它會給出空指針異常....我該怎麼做呢? – Mike 2012-08-19 23:37:05

+0

@Mike看到我的文章;-) – oldrinb 2012-08-19 23:52:20

1

您的equals方法和您的hashcode方法都執行不正確。

  • equals方法返回false當兩個對象null成員。
  • 您對hashCode的實施可以爲比較相同的某些對象返回不同的哈希碼。

您必須提供的equalshashCode正確的實現,以能夠使用你的對象在HashSet

+0

...你能幫我糾正它...如果我刪除null檢查fName在equals方法,它給空指針異常....然後,我該怎麼做? – Mike 2012-08-19 23:42:49

+0

@Mike:你用什麼IDE?幾乎所有體面的IDE都可以給你一個equals和hashCode的工作實現。生成它們,然後根據需要進行調整(例如添加不區分大小寫)。請記住,您所做的每個更改都必須反映在hashCode中。 – 2012-08-19 23:44:05