我正在尝试存储一组可能的选择并消除重复,因此我将我在HashSet
中所做的选择存储起来。每个步骤我有两个数据,两者的组合不能是唯一的,以便它被认为是重复的(例如[2,0],[0,2],[2,2]都是新的步骤,但后来[2,2]将是重复的)。
我认为我需要覆盖equals
才能正确判断该步骤是否已经在HashSet
但我没有使用自定义类,只是Integers
的数组,所以我发现的大部分内容都不适用(据我所知)。 This seems like it may be useful,建议继承HashSet
的可能性,但如果可能,我想避免这种情况。我希望我已经注释掉的equals
方法可以工作,但它从未调用过。我是否还需要覆盖hashCode()
?我知道它们是齐头并进的。我只需要去写自己的课程,还是有其他方法可以做我想做的事情?
import java.util.HashSet;
public class EP2 {
public static long count = 0;
public static HashSet<Integer []> visits = new HashSet<Integer []>();
//@Override
//public boolean equals(Object j){
// return true;
//}
public static void main(String[] args) {
int position = 0;
int depth = 0;
walk(position, depth);
System.out.println(count);
}
public static void walk(int position, int depth){
count++;
Integer[] specs = new Integer[2];
specs[0] = position;
specs[1] = depth;
visits.add(specs);
Integer[] specL = new Integer[]{position - 1, depth+1};
Integer[] specR = new Integer[]{position + 1, depth+1};
//doesn't avoid [0,2] duplicates
if(depth < 2){
if(!visits.contains(specL)){
walk(position - 1, depth+1); //walk left
}
if(!visits.contains(specR)){
walk(position + 1, depth+1); //walk right
}
}
}
}
答案 0 :(得分:2)
在Java中,hashCode()
和equals(Object)
一起使用。如果覆盖一个,则应覆盖另一个。当Java在HashSet
中查找对象时,它首先计算hashCode
以确定可以找到该对象的桶。然后它使用equals(Object)
来查看该集合是否具有该对象。此外,更改HashSet
中的对象会导致问题,因为它可能最终会出现在错误的存储桶中,并且永远不会再被发现。
您可能希望编写自己的不可变类Position
,其中包含构造函数,position
和depth
变量,getter,equals(Object)
和{{1 }}。 hashCode()
数组的成员具有意义,因此您应该明确说明这些。
答案 1 :(得分:1)
问题是equals()
Array
检查数组是否是同一个实例。在你的情况下,他们可能不是。查看一个很好的问题和答案here。
您的HashSet
将为集合中的所有元素调用equals()
,因此除非所有数组都是同一个实例,否则它将返回false
。
将数组更改为List
可能会有效,因为它会检查所有包含的元素是否彼此相等。对于Integer
,这当然有效。
答案 2 :(得分:1)
如果您只是想检查重复项,请编写一个自定义方法来检查一个集合是否包含int[]
。
public static boolean contains(HashSet<Integer []> set, int[] step) {
Iterator<Integer []> it = set.iterator();
boolean flag = false;
while(it.hasNext()) {
Integer[] inner = it.next();
if (step.length == inner.length) {
for (int i = 0; i < inner.length; i++) {
if (inner[i].equals(step[i]))
flag = true;
else
flag = false;
}
if (flag)
return true;
}
}
return false;
}
你应该遵循你的规则。例如,如果您知道数组的大小总是为2,那么您可能不需要进行检查,并且可以快速检查每个数组的相同索引处的每个值。
您可以在想要向Set添加内容时调用此方法。