2012-03-20 36 views
3

我有一個項目列表,其中每個項目是一個包含2個公共字符串的簡單類。 我有一個equals方法,簡單地使用兩個字符串的String的equalsIgnoreCase methot。從java清單中移除等於的項目

public class data 
{ 
    public String a; 
    public String b; 

    public boolean equals(data d) 
    { 
     if(a.equalsIgnoreCase(d.a) && b.equalsIgnoreCase(d.b)) 
     { 
      return true; 
     } 
     else 
     { 
      return false; 
     } 
    } 
} 

我希望能夠刪除的元素,即使它不是一個列表的同一個實例,但等於它。

現在我這樣做:

public void remove(data dataToRemove) 
{ 
    for(data i : _list) 
    { 
     if(i.equals(dataToRemove)) 
     { 
      _list.remove(i); 
      break; 
     } 
    } 
} 

有沒有更好的方式來做到這一點?

+0

這應該工作 – scibuff 2012-03-20 17:32:37

+0

取決於如何重要的順序是到您的收藏你可以考慮使用一個地圖,像[HashMap中(http://docs.oracle.com/javase/6/docs/api/的java/UTIL/HashMap.html)。這樣你就可以通過鍵查找你的對象。這比使用循環更好,但並不總是必要的。 – Shaded 2012-03-20 17:36:09

+0

列表不是此練習的最佳容器。 – Woot4Moo 2012-03-20 17:37:31

回答

15

幾點意見:

  • equals方法覆蓋的Objectequals方法(參數應該是Object類型,而不是data類型)。
  • 您應該改善equals法覈算空等
  • 最後,你應該重寫hashcode()過,當你重寫equals() - 如果你不使用可能會設置或地圖,例如當遇到一些奇怪的行爲。

如果您正確覆蓋了equals方法,則可以使用remove方法。 查看下面自動生成的equalshashcode生成的Netbeans,修改爲使用equalsIgnoreCase的方法。

public static void main(String[] args) { 
    List<Data> list = new ArrayList<Data>(); 
    list.add(new Data("a", "b")); 
    list.add(new Data("a", "c")); 
    System.out.println(list.size()); //2 
    list.remove(new Data("A", "b")); 
    System.out.println(list.size()); //1 
} 

public static class Data { 

    public String a; 
    public String b; 

    public Data(String a, String b) { 
     this.a = a; 
     this.b = b; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (obj == null) return false; 
     if (getClass() != obj.getClass()) return false; 
     final Data other = (Data) obj; 
     boolean sameA = (this.a == other.a) || (this.a != null && this.a.equalsIgnoreCase(other.a)); 
     if (!sameA) return false; 
     boolean sameB = (this.b == other.b) || (this.b != null && this.b.equalsIgnoreCase(other.b)); 
     if (!sameB) return false; 
     return true; 
    } 

    @Override 
    public int hashCode() { 
     int hash = 3; 
     hash = 89 * hash + (this.a == null ? 0 :this.a.toUpperCase().hashCode()); 
     hash = 89 * hash + (this.b == null ? 0 : this.b.toUpperCase().hashCode()); 
     return hash; 
    } 

} 
+0

非常感謝您的快速和完整的答案!這非常有幫助。 – 2012-03-20 17:43:01

+0

這是合適的方法(重寫equals,以及hashCode,它應該總是和equals一起被覆蓋),但是自動生成的equals等於上面的值與他使用的等於(他可以重新實現的東西)不匹配。 – pickypg 2012-03-20 17:47:51

+1

@pickypg我已經做了相應的修改 – assylias 2012-03-20 17:51:10

1

最簡單的方法是隻需調用Remove方法的列表而不用任何循環,並將參數傳遞給對象。它使用您在對象上定義的equals方法來查找並刪除列表中存在的方法。

_list.remove(data); 

您還沒有指定的hashCode方法,但是當你重寫equals方法的情況下,你應該總是創造一個習慣讓你用它在集合中就像一組或地圖。

+1

他的equals方法不會覆蓋Object.equals,因此刪除不會像預期的那樣工作。 – assylias 2012-03-20 17:39:50

+0

真是太棒了! @Override註釋證明它再次使用。 – Hiro2k 2012-03-20 17:42:03