最近我读了这篇文章 开发人员工作文件。
该文档是关于有效和正确地定义hashCode()和equals(),但我无法弄清楚为什么我们需要覆盖这两个方法。
我如何决定有效地实现这些方法?
最近我读了这篇文章 开发人员工作文件。
该文档是关于有效和正确地定义hashCode()和equals(),但我无法弄清楚为什么我们需要覆盖这两个方法。
我如何决定有效地实现这些方法?
当前回答
Bah -“你必须在每个重写equals()的类中重写hashCode()。”
[出自Joshua Bloch的《Effective Java》?]
Isn't this the wrong way round? Overriding hashCode likely implies you're writing a hash-key class, but overriding equals certainly does not. There are many classes that are not used as hash-keys, but do want a logical-equality-testing method for some other reason. If you choose "equals" for it, you may then be mandated to write a hashCode implementation by overzealous application of this rule. All that achieves is adding untested code in the codebase, an evil waiting to trip someone up in the future. Also writing code you don't need is anti-agile. It's just wrong (and an ide generated one will probably be incompatible with your hand-crafted equals).
他们肯定应该在被写来用作键的对象上强制设置一个接口吗?无论如何,Object永远不应该提供默认的hashCode()和equals() imho。它可能鼓励了许多破碎的散列集合。
但无论如何,我认为“规则”是前后颠倒的。与此同时,我将继续避免使用“等号”进行相等性测试方法:-(
其他回答
为了在HashMap, Hashtable等集合中使用我们自己的类对象作为键。,我们应该通过了解集合的内部工作来重写这两个方法(hashCode()和equals())。否则,它会导致我们意想不到的错误结果。
String类和包装器类的equals()和hashCode()方法实现与Object类不同。Object类的equals()方法比较对象的引用,而不是内容。Object类的hashCode()方法为每个对象返回不同的hashCode,无论内容是否相同。
It leads problem when you use Map collection and the key is of Persistent type, StringBuffer/builder type. Since they don't override equals() and hashCode() unlike String class, equals() will return false when you compare two different objects even though both have same contents. It will make the hashMap storing same content keys. Storing same content keys means it is violating the rule of Map because Map doesnt allow duplicate keys at all. Therefore you override equals() as well as hashCode() methods in your class and provide the implementation(IDE can generate these methods) so that they work same as String's equals() and hashCode() and prevent same content keys.
你必须重写hashCode()方法和equals(),因为equals()根据hashCode工作。
此外,与equals()一起重写hashCode()方法有助于完好无损equals()-hashCode()契约:“如果两个对象相等,那么它们必须具有相同的哈希码。”
什么时候需要为hashCode()编写自定义实现?
正如我们所知,HashMap的内部工作是基于哈希原理的。条目集存储在特定的存储桶中。您可以根据自己的需求定制hashCode()实现,以便相同的类别对象可以存储在相同的索引中。 当你使用put(k,v)方法将值存储到Map集合中时,put()的内部实现是:
put(k, v){
hash(k);
index=hash & (n-1);
}
意思是,它生成索引,索引是基于特定键对象的hashcode生成的。所以让这个方法根据你的需求生成哈希码,因为相同的哈希码条目集将存储在相同的桶或索引中。
就是这样!
我正在研究解释“如果你只覆盖hashCode,那么当你调用myMap.put(first,someValue)时,它首先接受,计算它的hashCode并将其存储在给定的桶中。然后,当你调用myMap.put(first,someOtherValue)时,它应该根据Map文档将first替换为second,因为它们是相等的(根据我们的定义)。”:
我认为第二次添加myMap时应该是第二个对象比如myMap。put(second,someOtherValue)
它在使用值对象时很有用。以下摘自Portland Pattern Repository:
Examples of value objects are things like numbers, dates, monies and strings. Usually, they are small objects which are used quite widely. Their identity is based on their state rather than on their object identity. This way, you can have multiple copies of the same conceptual value object. So I can have multiple copies of an object that represents the date 16 Jan 1998. Any of these copies will be equal to each other. For a small object such as this, it is often easier to create new ones and move them around rather than rely on a single object to represent the date. A value object should always override .equals() in Java (or = in Smalltalk). (Remember to override .hashCode() as well.)
Java提出了一个规则
如果使用Object类的equals方法,两个对象相等,那么hashcode方法应该为这两个对象提供相同的值。
因此,如果在我们的类中重写equals(),我们也应该重写hashcode()方法来遵循此规则。 例如,equals()和hashcode()这两个方法都用于Hashtable中以键值对的形式存储值。如果我们覆盖其中一个而不是另一个,如果我们使用这样的对象作为键,哈希表可能不会像我们想要的那样工作。