這裏是你的選擇。所有這些解決方案都需要正確實施equals
和hashCode
。既然你想row
和col
是唯一的:
public boolean equals(Object obj) {
if (obj == null || obj.getClass() != Node.class) {
return false;
}
Node other = (Node) obj;
if (other.col != this.col) {
return false;
}
if (other.row != this.row) {
return false;
}
return true;
}
public int hashCode() {
int result = 7;
result += row * 31;
result += col * 31;
return result;
}
遍歷列表
你不必自己做迭代,但是這正是呼籲List.contains
會做。這一個很容易:
if (!myList.contains(node)) {
myList.add(node);
}
這將爲你迭代,所以你不必編寫循環。
目錄設置到列表
這裏有兩個子選項。如果您想保留輸入列表的順序,那麼您可以使用LinkedHashSet
。如果你不在乎,你可以使用HashSet
。我的意思是,如果我有一個List
與元素A,B,C,將其轉換爲HashSet
和後面可能會產生一個不同的列表,如B,C,A LinkedHashSet
保持元素按插入順序,避免此問題。在任何情況下,你只是這樣做:
Set<Node> nodeSet = new [Linked]HashSet<Node>(myList);
nodeSet.add(node);
myList = new ArrayList<Node>(nodeSet);
請記住,這基本上是做迭代爲好,但它使用哈希碼的快捷方式,而不是檢查每一個元素的平等,這可能是一個大問題與足夠的節點。如果你的節點列表很小(少於1000個元素),那麼我懷疑這會造成很大的不同,你也可以使用第一個。
轉換一切Set
您剛纔提到,這將需要大量的重構你的代碼,但是這並不是一件壞事,特別是如果你打算在這個代碼的工作很多未來。我的經驗法則是,如果重構會使代碼更容易維護,那麼添加一點額外的開發時間就是從來沒有一件壞事。編寫可維護,可讀和易懂的代碼is what the experts do(這裏的問題不相關,但是這個特定的答案是)。由於Set
意味着獨特的元素,並且List
不會,因此進行更改是有意義的。編譯器幾乎可以告訴你所有的地方你必須改變它的錯誤,並且可能比你想象的要更少的時間。
換句話說。爲了保持它更乾淨,我應該重構爲'Set'並覆蓋'equals()'方法? – JavaCake
和'hashCode()',但是。 – Brian
即使它變成了'O(N)',我仍然很想穿越整個列表。 – JavaCake