java.util.HashMap和HashSet的内部实现
我一直在试图理解java.util.HashMap和HashSet的内部实现,java,hashmap,hashcode,hashset,language-implementation,Java,Hashmap,Hashcode,Hashset,Language Implementation,我一直在试图理解java.util.HashMap和java.util.HashSet的内部实现 以下是我脑海中闪现的疑惑: 在HashMap/HashSet中,@Override public int hashcode()的重要性是什么?该哈希代码在何处内部使用 我通常看到HashMap的键是一个字符串像myMap。我是否可以将值映射到someObject(而不是字符串),如myMap?我需要遵守哪些合同才能成功实现这一点 提前谢谢 编辑: 我们是说密钥(check!)的散列码是散列表中映射值
java.util.HashMap
和java.util.HashSet
的内部实现
以下是我脑海中闪现的疑惑:
@Override public int hashcode()
的重要性是什么?该哈希代码在何处内部使用字符串
像myMap
。我是否可以将值映射到someObject
(而不是字符串),如myMap
?我需要遵守哪些合同才能成功实现这一点myMap.get(someKey)时
java正在内部调用someKey.hashCode()
,以获取哈希表中要查找结果值的数字java.util.HashSet
中,从何处生成哈希表的键?是我们正在添加的对象,例如mySet.add(myObject)然后myObject.hashCode()
将决定此文件在哈希表中的位置?(因为我们不在哈希集中给出键)someObject
(而不是String
)例如myMap
是,但someObject
必须是类,而不是对象(您的名称表明您要传入对象;它应该是someObject
,以明确您指的是类型)
我需要遵守哪些合同才能成功实现这一点
类必须实现hashCode()
和equals()
[编辑]
我们是说密钥(check!)的散列码是散列表中映射值的实际对象吗
是的。在Java中,equals()、
hashcode()
和哈希表(以及.NET)之间存在着复杂的关系。引用文件:
public int hashCode()
返回对象的哈希代码值。支持此方法是为了使哈希表受益,例如java.util.Hashtable
提供的哈希表
hashCode的总合同为:
- 在Java应用程序的执行过程中,每当在同一对象上多次调用hashCode方法时,只要没有修改对象上的equals比较中使用的信息,hashCode方法必须始终返回相同的整数。从应用程序的一次执行到同一应用程序的另一次执行,该整数不必保持一致李>
- 如果根据equals(Object)方法两个对象相等,那么对两个对象中的每一个调用hashCode方法必须产生相同的整数结果李>
- 如果根据equals(
)方法,两个对象是不等的,那么对这两个对象中的每一个调用java.lang.Object
方法都必须产生不同的整数结果。但是,程序员应该知道,为不相等的对象生成不同的整数结果可能会提高哈希表的性能hashCode
Object
定义的hashCode
方法会为不同的对象返回不同的整数。(这通常是通过将对象的内部地址转换为整数来实现的,但Java不需要这种实现技术™ 编程语言。)
线路
@Overrides public int hashCode()
只告诉您,
hashCode()
方法被覆盖。这通常表示在HashMap
中使用类型作为键是安全的
是的,您可以轻松地使用符合HashMap
中equals()
和hashCode()
契约的任何对象作为键
对象
都必须有hashCode()
方法HashMap
和HashSet
都不是异常。如果将哈希映射/集插入另一个哈希映射/集,则使用此哈希代码HashMap
/HashSet
中的键。这要求hashCode()
方法为相等的对象返回相等的值,并且equals()
方法根据契约(自反、传递、对称)实现。Object
中的默认实现已经遵守这些约定,但是如果希望值相等而不是引用相等,则可能需要覆盖它们对。您可以使用任何对象作为HashMap中的键。为了做到这一点,以下是您必须遵循的步骤
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}
public V put(K键,V值){
if(key==null)
重新
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
private transient HashMap<E,Object> map;
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}