Java 是否正确使用HashSet.contains()?
我试图用Kruskal算法的一个版本生成一个迷宫。我需要检查int[]数组中的一些坐标,例如[1,5]是否在现有集合中 这是代码部分的副本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%确信它至少应
// 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的期望。