Java 是否正确使用HashSet.contains()?

Java 是否正确使用HashSet.contains()?,java,contains,hashset,Java,Contains,Hashset,我试图用Kruskal算法的一个版本生成一个迷宫。我需要检查int[]数组中的一些坐标,例如[1,5]是否在现有集合中 这是代码部分的副本 // find sets containing cells to be joined for (HashSet<int[]> h : cells) { if (h.contains(new int[]{x, y - 2})) { set1 = h; } } 问题是if语句从来都不是真的,但我99.9%确信它至少应

我试图用Kruskal算法的一个版本生成一个迷宫。我需要检查int[]数组中的一些坐标,例如[1,5]是否在现有集合中

这是代码部分的副本

// find sets containing cells to be joined
for (HashSet<int[]> h : cells) {
    if (h.contains(new int[]{x, y - 2})) {
        set1 = h;
    }
}
问题是if语句从来都不是真的,但我99.9%确信它至少应该是真的一次

我是否使用HashSet.contains错误

谢谢

哈希集包含Java中的方法 util。HashSet contains方法用于检查HashSet中是否存在特定元素。所以基本上它是用来检查一个集合是否包含任何特定的元素

我是否使用HashSet.contains错误

好吧,你有一个错误的期望,但它更多的是关于数组而不是关于HashSet。Java中的数组并不像您期望的那样实现equals和hashCode。它们有效地表现出引用平等行为。例如:

int[]数组1={1}; int[]array2={1}; System.out.printlnaray1.equalsaray1;//真-相同引用 System.out.printlnaray1.equalsaray2;//错误-不同引用 我建议创建一个包含x和y字段的坐标类,而不是使用int[]作为坐标。若那个坐标类适当地重写了equals和hashCode,那个么使用HashSet就可以了。尽管我建议您在循环之外而不是在每次迭代中创建要查找的对象。

我认为这将有助于:

Stream.generate(() -> new int[] { 1, 2 }.hashCode()).limit(3).forEach(System.out::println);
注意,我们将[1,2]的哈希代码打印三次,但得到三个唯一的值。这是因为每个新int[]都有不同的哈希代码。创建自定义类型,重写hashCode并将其添加到HashSet中。差不多

public class Cell {
    private final int x, y;

    public Cell(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    @Override
    public int hashCode() {
        return 13 ^ x ^ y;
    }

    @Override
    public boolean equals(Object o) {
        if (o == null) {
            return false;
        } else if (this == o) {
            return true;
        } else if (o instanceof Cell) {
            Cell c = (Cell) o;
            return this.x == c.x && this.y == c.y;
        }
        return false;
    }
}

更多信息:先生,你的答案总是正确的。我建议将单元格或坐标类设置为不可变。除此之外,在将对象添加到HashSet后,以影响hashcode的方式对其进行变异将打破HashSet的期望。