2012-04-17 148 views
0

,同时通过凯西塞拉利昂的书要我碰到这个代码片段跌跌撞撞:散列函数和密钥

m.put("k1", new Dog("aiko")); // add some key/value pairs 
m.put("k2", Pets.DOG); 
m.put(Pets.CAT, "CAT key"); 
Dog d1 = new Dog("clover"); 
m.put(d1, "Dog key"); 
m.put(new Cat(), "Cat key"); 

地图是用来储存东西在键和值格式。当我们输入“k1”或新的Cat()作为关键字时,有人会告诉我实际存储在密钥中的内容吗?是否存储对这些对象的引用或散列码的值?我完全同意这一点。请指教。

如果您能指引我阅读更多的阅读材料,我们将不胜感激。

回答

0

它将由您的对象定义。

您必须创建一个hashCode()和一个equals()方法,以便它可以存储在您的散列表中。

尽管合理实际,类Object定义的hashCode方法确实为不同的对象返回不同的整数。 (这一般是通过将该对象的内部地址转换成一个整数来实现的,但不是由的JavaTM编程语言不需要这种实现技巧。)

参见在java.lang.Object中http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Object.html#hashCode(Javadoc中)

,或者你可以阅读这一个解释 http://www.javaworld.com/javaworld/javaqa/2002-06/01-qa-0621-hashtable.html

我希望它能帮助

2

该地图是N个桶的阵列。

put()方法首先在您的密钥上调用hashCode()。从这个哈希码中,它使用一个模来获得地图中桶的索引。

然后,它遍历存储在与找到的存储桶关联的链接列表中的条目,并使用equals()方法将每个条目关键字与您的关键字进行比较。

如果一个条目具有与您的密钥相同的密钥,则其值由新值替换。否则,将使用新密钥和新值创建一个新条目,并将其存储在与存储桶关联的链接列表中。

由于Cat实例和String实例永远不会相等,因此与String关键字关联的值将永远不会通过将与Cat关联的值进行修改。

0

当使用HashMap时,其中的键是唯一的。在Java中,根据equals()和hashCode()方法的定义检查这些键的唯一性,即所考虑的对象的类所提供的类。

这是通过首先比较使用equals()方法并且如果它返回相等然后使用hashCode()进行比较来完成的。另外,你必须知道指向一个对象的每个引用都有一个位模式,对于引用同一对象的多个引用可能不同。

因此,一旦equals()测试通过,对象将不会插入到地图中,因为地图应该具有唯一的键。因此,作为映射关键字的对象的每个hashCode值将为一系列hashCode值形成不同的桶,并且该对象将相应地分组。

EDIT提供一种例如:

例如,让我们考虑两个对象具有值“你好”和“hlleo”的字符串的属性,并假设哈希码()函数被编程为使得对象的散列码是String属性中字符的ASCII值的总和,如果String属性的值相等,则equals()方法返回true。

因此,在上述情况下,equals()返回false,因为字符串不相等,但hashCode将相同。所以这两个对象将被放置在相同的散列码桶中。

希望有所帮助。

+0

这显然是错误的。平等仅限于等同。 hashCode用于减少潜在的相等候选数。两个相等的对象必须具有相同的hashCode。 – 2012-04-17 15:46:49

+0

这是正确的,但你的回答说equals首先被调用,然后如果equals返回true,则使用hashCode。这完全不正确。阅读我的答案,了解它是如何工作的。 – 2012-04-17 18:08:58

+0

那么,是不是它先hashCode()然后equals()?纠正我,如果我错了。非常感谢您更新我的知识。 – TechSpellBound 2012-04-17 18:26:18