0

我正在尝试存储一组可能的选择并消除重复项,因此我将我所做的选择存储在HashSet. 我的每一步都有两条数据,两者的组合不能唯一,这样才能被认为是重复的(例如 [2,0]、[0,2]、[2,2] 都是新的步骤,但随后转到 [2,2] 将是重复的)。

我相信我需要重写equals以正确确定步骤是否已经在HashSet但我没有使用自定义类,只是一个数组Integers,所以我发现的大部分内容都不适用(据我所知)。这似乎很有用,暗示了子类化的可能性,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
        }
    }

 }  

}
4

3 回答 3

2

在Java中,hashCode()一起equals(Object)去。如果你覆盖一个,你应该覆盖另一个。当 Java 在 a 中查找对象时HashSet,它首先计算hashCode以确定该对象可能在哪个存储桶中找到。然后它使用equals(Object)来查看该集合是否具有该对象。此外,更改 a 中的对象HashSet会导致问题,因为它可能最终在错误的存储桶中,并且再也找不到了。

您可能想要编写自己的不可变类 ,Position其中包含构造函数、apositiondepth变量、getterequals(Object)hashCode()。数组的成员是Integer[]有意义的,所以你应该明确说明这些。

于 2013-05-23T13:37:54.787 回答
1

如果您只是尝试检查重复项,请编写一个自定义方法来检查 Set 是否包含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 中添加某些内容时,您都可以调用此方法。

于 2013-05-23T13:48:06.557 回答
1

问题是检查equals()数组Array是否是同一个实例。在你的情况下,他们可能不是。在这里查看一个很好的问题和答案。

HashSet将调用集合中的所有元素,因此除非所有数组都是相同的实例,否则equals()它将返回。false

将数组更改为 aList可能会起作用,因为它会检查所有包含的元素是否彼此相等。对于Integers,这当然有效。

但是,我会实现我自己的课程。如果您没有任何此类限制,则应该这样做。

于 2013-05-23T13:38:24.417 回答