HashSet如何处理hashCode()? [英] How HashSet works with regards to hashCode()?

查看:125
本文介绍了HashSet如何处理hashCode()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图更深入地理解java.util.Collection和java.util.Map,但我对HashSet funcionality有一些疑惑:



在文档它说:这个类实现了Set接口,它由一个哈希表(实际上是一个HashMap实例)支持。好的,我可以看到HashSet总是有一个Hashtable在后台工作。哈希表是一个结构,每次要向其中添加新元素时,都会要求输入一个键和一个值。然后,将值和密钥存储在基于密钥hashCode的存储桶中。如果两个键的哈希码相同,则使用链接列表将这两个键值添加到同一个存储桶中。所以,我的问题是:如果一个HashSet总是有一个Hashtable在后台运行,那么每次我们添加一个新的元素到HashSet使用HashSet.add()方法,HashSet应该将它添加到它的内部Hashtable中。但是,Hashtable要求值,所以它使用什么密钥?它是否仅使用我们试图添加的值作为关键字,然后取其hashCode?如果我在HashSet实现中说错了什么,请纠正我。



另一个问题是:通常,哪些类可以使用java的hashCode()方法目的?我这样问是因为在文档中,它说每次我们重写equals()方法时,我们都需要重写hashCode()方法。好吧,这真的很有道理,但是我的疑问是,如果这只是我们应该做的一个建议,以保持一切的美好和完美(以这种方式),或者真的有必要,因为也许很多Java默认类会不断地使用对象的hashCode()方法。在我看来,我看不到其他类使用这种方法,而不是与Collections相关的类。非常感谢你们

解决方案

如果你看看HashSet的实际java代码,你可以看到它的作用:

  //与支持Map中的Object关联的虚拟值
private static final Object PRESENT = new Object();
...

public boolean add(E e){
return map.put(e,PRESENT)== null;





$ b因此你添加的元素是支持hashmap中的Key,价值作为价值。这个虚拟值永远不会被hashSet实际使用。



关于重写equals和hashcode的第二个问题:

如果您想覆盖其中的任何一个,则必须始终覆盖两者。这是因为hashCode的约定表示相同的对象必须具有相同的哈希码。因此,如果你重写equals()而不是hashcode(),这可能发生。

  object1.equals(object2)// true 

MySet.add(object1);

MySet.contains(object2); // false,但如果我们取消hashcode(),应该是true

因为contains将使用hashcode来查找我们可能会得到一个不同的存储桶并且找不到相同的对象。


I'm trying to understand java.util.Collection and java.util.Map a little deeper but I have some doubts about HashSet funcionality:

In the documentation, it says: This class implements the Set interface, backed by a hash table (actually a HashMap instance). Ok, so I can see that a HashSet always has a Hashtable working in background. A hashtable is a struct that asks for a key and a value everytime you want to add a new element to it. Then, the value and the key are stored in a bucket based on the key hashCode. If the hashcodes of two keys are the same, they add both key values to the same bucket, using a linkedlist. Please, correct me if I said something wrong.

So, my question is: If a HashSet always has a Hashtable acting in background, then everytime we add a new element to the HashSet using HashSet.add() method, the HashSet should add it to its internal Hashtable. But, the Hashtable asks for a value and a key, so what key does it use? Does it just uses the value we're trying to add also as a key and then take its hashCode? Please, correct me if I said something wrong about HashSet implementation.

Another question that I have is: In general, what classes can use the hashCode() method of an java object? I'm asking this because, in the documentation, it says that everytime we override equals() method we need to override hashCode() method. Ok, it really makes sense, but my doubt is if it's just a recommendation we should do to keep everything 'nice and perfect' (putting in this way), or if it's really necessary, because maybe a lot of Java defaults classes will constantly uses hashCode() method of your objects. In my vision, I can't see other classes using this method instead of those classes related to Collections. Thank you very much guys

解决方案

If you look at the actual javacode of HashSet you can see what it does:

 // Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
...

 public boolean add(E e) {
    return map.put(e, PRESENT)==null;
}

So the element you are adding is the Key in the backing hashmap with a dummy value as the value. this dummy value is never actually used by the hashSet.

Your second question regarding overriding equals and hashcode:

It is really necessary to always override both if you want to override either one. This is because the contract for hashCode says equal objects must have the same hashcode. the default implementation of hashcode will give different values for each instance.

Therefore, if you override equals() but not hashcode() This could happen

object1.equals(object2) //true

MySet.add(object1);

MySet.contains(object2); //false but should be true if we overrode hashcode()

Since contains will use hashcode to find the bucket to search in we might get a different bucket back and not find the equal object.

这篇关于HashSet如何处理hashCode()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆