【问题标题】:Overriding equals without custom class在没有自定义类的情况下覆盖等于
【发布时间】:2013-05-18 21:19:54
【问题描述】:

我正在尝试存储一组可能的选择并消除重复项,因此我将我所做的选择存储在 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
        }
    }

 }  

}

【问题讨论】:

  • 听起来像只使用Point 可能会满足您的需求。
  • 我不明白。为什么不能简单地用一对ints 创建一个新类?
  • 我不知道它存在,但在这种情况下是的,我可以接受。谢谢。但是,我仍然希望回答这个问题
  • @BalázsMáriaNémeth 我可以,但我很好奇以当前的方式解决问题。那样我不会学到那么多。
  • 但是这个问题对我来说并没有真正的意义。您不能覆盖 Integer[] 的 equals,因为那甚至不是一个类 :)

标签: java equals contains hashset overriding


【解决方案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,那么也许您不需要进行检查,并且可以快速检查每个数组相同索引处的每个值。

你可以在任何时候调用这个方法来添加一些东西到集合中。

【讨论】:

    【解决方案2】:

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

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

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

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 2017-12-14
        • 2019-06-29
        • 2019-08-13
        • 2020-01-12
        • 2014-01-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-14
        相关资源
        最近更新 更多