java HashSet 'add' 方法何时调用等于?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14504901/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 16:28:54  来源:igfitidea点击:

When does HashSet 'add' method calls equals?

javacomparisonequalshashset

提问by Hernán Eche

I did this test in a HashSet comparision and equalsis not being called

我在 HashSet 比较中做了这个测试并且equals没有被调用

I would like to consider equals when farAway=false (A function to check two point distances)

我想在 farAway=false 时考虑等于(检查两点距离的函数)

Full compilable code, you could test it, and tells why equals is not being called in this example.

完整的可编译代码,您可以对其进行测试,并说明为什么在此示例中未调用 equals。

public class TestClass{
     static class Posicion
    {
        private int x;
        private int y;

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Posicion other = (Posicion) obj;
            if ( farAway(this.x, other.x, this.y, other.y,5)){   
                return false;
            } 
            return true;
        }

        @Override
        public int hashCode() {
            int hash = 7; hash = 59 * hash + this.x; hash = 59 * hash + this.y;
            return hash;
        }

         Posicion(int x0, int y0) {
            x=x0;
            y=y0;
        }

        private boolean farAway(int x, int x0, int y, int y0, int i) {
            return false;
        }
    }

    public static void main(String[] args) {
        HashSet<Posicion> test=new HashSet<>();
        System.out.println("result:"+test.add(new Posicion(1,1)));
        System.out.println("result:"+test.add(new Posicion(1,2)));
    }
}

EDIT

编辑

-Is there a way to force HashSet add to call equals?

- 有没有办法强制 HashSet 添加调用等于?

回答by NPE

If the hash codes differ, there is no need to call equals()since it is guaranteed to return false.

如果哈希码不同,则无需调用,equals()因为它保证返回false

This follows from the general contracton equals()and hashCode():

这来自于和的总合同equals()hashCode()

If two objects are equal according to the equals(Object)method, then calling the hashCodemethod on each of the two objects must produce the same integer result.

如果两个对象根据equals(Object)方法相等,则hashCode对两个对象中的每一个调用该方法必须产生相同的整数结果。

Right now your class is breaking that contract. You need to fix that.

现在您的班级正在违反该合同。你需要解决这个问题。

回答by Sebastian Krysmanski

If you want equals()to be called always, just always return, say, 0in hashCode(). This way all items have the same hash code and are compared purely with equals().

如果您想equals()始终被调用,只需始终返回,例如0in hashCode()。这样,所有项目都具有相同的哈希码,并且纯粹与equals().

public int hashCode() {
  return 0;
}

回答by David Lavender

It sounds like HashSet isn't right for you. It sounds like you want a custom way of comparing two positions. Rather than saying "are two positions exactly equal?". Instead, you should look at using TreeSet, with a Comparator. This way, you can write a "IsWithinRangeComparator" and do your range checking there.

听起来 HashSet 不适合您。听起来您想要一种比较两个位置的自定义方式。而不是说“两个位置完全相等吗?”。相反,您应该考虑使用带有比较器的 TreeSet。这样,您可以编写一个“IsWithinRangeComparator”并在那里进行范围检查。

回答by Zenil

As suggested above,when objects are equal, their hashcode should also be the same. You could make a simple fix to your hashcode computation like below.

如上所述,当对象相等时,它们的哈希码也应该相同。您可以对哈希码计算进​​行简单的修复,如下所示。

 public int hashCode() {

int hash = 7; hash = 59 * hash + this.x; hash = 59 * hash + this.y;
boolean faraway=farAway(this.x, other.x, this.y, other.y,5);
hash=59*hash+(faraway?1:0); //include faraway also as part of hashcode computation

 return hash;

}

}