这是您的选择。所有这些解决方案都需要正确实施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
您不必自己进行迭代,但这正是调用List.contains
将要做的。这个很简单:
if (!myList.contains(node)) {
myList.add(node);
}
这将为您进行迭代,因此您不必编写循环。
List
到Set
_List
这里有两个子选项。如果要保留输入列表的顺序,则可以使用LinkedHashSet
. 如果你不在乎,你可以使用HashSet
. 我的意思是,如果我有一个List
带有元素 A、B、C 的 a,将其转换为 aHashSet
并返回可能会产生一个不同的列表,例如 B、C、A。LinkedHashSet
保持元素的插入顺序,避免了这个问题。无论如何,您只需这样做:
Set<Node> nodeSet = new [Linked]HashSet<Node>(myList);
nodeSet.add(node);
myList = new ArrayList<Node>(nodeSet);
请记住,这本质上也是在进行迭代,但它使用的是哈希码快捷方式,而不是检查每个元素的相等性,这对于足够多的节点来说可能是一件大事。如果您的节点列表很小(少于 1000 个元素),那么我怀疑这会产生很大的不同,您不妨使用第一个。
将所有内容转换为Set
您提到这将需要对您的代码进行大量重构,但这并不是一件坏事,特别是如果您计划在未来大量处理此代码。我的经验法则是,如果重构将使代码更易于维护,那么增加一点额外的开发时间绝不是一件坏事。编写可维护、可读和可理解的代码是专家所做的(这里的问题不相关,但这个特定的答案是)。既然Set
暗示了独特的元素而List
不是,那么做出改变是有意义的。编译器几乎会告诉你所有你必须用它的错误来改变的地方,而且它可能比你想象的要花更少的时间。