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

标签 java arraylist duplicates

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

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/

相关文章:

java - 找出调用我的方法

java - 将 LinkedHashMap 对象添加到 ArrayList 中

mysql - 是否可以在 MySQL 更新语句中标记重复记录?

python - 在 Python 中计算重复整数

java - Java中按字典顺序排列的整数ArrayList的ArrayList

java - 没有重复项的可排序 Java 集合

java - Android 设备上的缅甸字体 - 整个应用程序

java - 在selenium JAVA中提取文本br标签

java - 在java中解压没有第一个目录

java - 如何处理 ArrayListAdapter 的 onListItemClick 内的项目?