gpt4 book ai didi

java - 使用自定义对象消除或避免在 ArrayList 中添加重复项

转载 作者:行者123 更新时间:2023-11-30 06:27:35 25 4
gpt4 key购买 nike

我在这个结构中有一个自定义对象

static class Node {
int col;
int row;
int g;
int h;
int f;

public Node(int col, int row, int g, int h) {
this.col = col;
this.row = row;
this.g = g;
this.h = h;
this.f = g+h;
}
}

colrow变量是唯一的,并且只能在 ArrayList<Node> myList 中出现一次.

有没有一种最佳方法可以避免添加或检查可能的重复项,而不必进行讨厌的 for 循环?

我知道 Set接口(interface)可能是一个解决方案,因为不会出现重复,但我现在有很多代码,除非有必要,否则我不想重构。

最佳答案

这是您的选择。所有这些解决方案都需要正确实现 equalshashCode。由于您希望 rowcol 是唯一的:

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);
}

这将为您迭代,因此您不必编写循环。

ListSetList

这里有两个子选项。如果您想保留输入列表的顺序,则可以使用 LinkedHashSet。如果你不在乎,你可以使用HashSet。我的意思是,如果我有一个包含元素 A、B、C 的 List,将其转换为 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 没有,因此进行更改是有意义的。编译器几乎会告诉您所有需要更改的地方及其错误,并且它可能比您想象的要少。

关于java - 使用自定义对象消除或避免在 ArrayList 中添加重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13253424/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com