import java.util.*;
class Dog {
public Dog(String n) { name = n; }
public String name;
public boolean equals(Object o) {
System.out.println("equals called..");
if((o instanceof Dog) &&
(((Dog)o).name == name)) {
return true;
} else {
return false;
}
}
public int hashCode() {
System.out.println("hashCodecalled..");
return name.length();
}
}
class SampleClass {
public static void main(String[] args) {
Map<Object, String> m = new HashMap<Object, String>();
Dog d1 = new Dog("clover");
m.put(d1, "Dog key");
d1.name ="arthur";
System.out.println(m.get(d1));
}
}
在上面的代码中,我得到的输出是:
hashCodecalled..
hashCodecalled..
Dog key
在我做 d1.name 之后=“亚瑟”
我期望输出是
hashCodecalled..``
hashCodecalled..
equals called..
null
请参见java.util.HashMap。获取方法代码。
它首先检查键是否== e.key然后检查key.equals(e.key)。
在您的代码中,您将同一个实例传递给get方法。所以key == e.key .和key.equals(e.key)不会被执行。
public V get(Object key) {
if (key == null)
return getForNullKey();
int hash = hash(key.hashCode());
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
return e.value;
}
return null;
}
这个问题以前在这里问过。
根据hashCode方法,它声明“如果两个对象根据equals(Object)方法相等,那么在两个对象的每一个上调用hashCode方法必须产生相同的整数结果。”一般来说,无论何时创建equals方法,都要确保它与返回的hashcode值一致。
HashMap总是在equal方法之前使用hashCode来比较对象。对于您的情况,如果您希望看到equal方法被调用,您可以通过将hashcode值设为常量来模拟哈希冲突场景。(注意:这是一个不错的例子,因为它对性能有很大影响。)
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Map<Object, String> m = new HashMap<Object, String>();
Dog d1 = new Dog("clover");
Dog d2 = new Dog("clover 2");
m.put(d1, "Dog 1");
m.put(d2, "Dog 2");
System.out.println(m.get(d1));
}
class Dog {
private String name;
public Dog(String n) {
name = n;
}
@Override
public boolean equals(final Object o) {
System.out.println("equals called..");
return true;
}
@Override
public int hashCode() {
System.out.println("hashCodecalled..");
return 1; // constant
}}
结果是:
hashCodecalled。。
hashCodecalled。。
等于调用..
hashCodecalled。。
狗 2
最后,您当然需要插入至少两个对象才能使其工作。
由于 HashMap
具有您要查找的确切对象,因此它不需要调用 equals
来验证该对象是否正确。
当您从 HashMap
获取
对象时,首先会评估 hashCode
以找到正确的存储桶。然后,搜索存储桶。但首先使用 ==
比较存储桶中的每个键。如果对象不是正在搜索的对象,则使用 equals
。
在Java 7中,在< code>HashMap的< code>get方法中,代码的关键部分是
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
return e.value;
为什么我需要再次使用hmap.put方法? 我的理解是这样的。 假设没有现有的键值对。所以,用 如果我在同一个实例中添加一个字符串,那么hashmap也应该自动更新,对吗?键=>列表对象。如果我添加到列表对象,那么对象引用不应该改变,对吗? 为什么我需要再次使用put方法并这样做?
和都有构造函数来设置初始容量,但提供以确保如果预期插入大量元素,内部数组已经增加。在某些情况下,也可能发生同样的事情。那么为什么没有确保容量的方法来保持存储桶准备就绪?
我编写了一个类,该类重写class Object中的equals(Object)方法,以使用对象的实例值将类类型的对象与类类型的其他对象进行比较。 当我将对象的一个实例作为键放在HashMap中,然后使用一个新的但相同的对象作为键调用映射上的get(object),它返回null。 我尝试将一个新的,相同的对象传递给equals方法,它返回true,所以问题不在于我的比较代码。 从我通过调试收集的
问题内容: 对于以下代码段, 产生的输出是 为什么即使我尝试在fun()中修改a的值也没有修改? a和指针z的地址为何相同但值却不同? const_cast是否有某种未定义的行为? 问题答案: const_cast是否有某种未定义的行为? 是的 ,您的程序包含未定义的行为。 这意味着您不能对它的输出有任何期望。原因由C ++ 11标准的7.1.6.1/4给出: 除了可以声明任何声明的类成员(7.1
我正在创建一个进行线性探测以查找键索引的哈希图。如果键已经在索引中,我想增加它的值,而不是向新索引添加一个。 例如,如果我得到字符串“五,五,五”的字数,我的输出是五1,五1,五1,而不是五3。 我认为一定是我的 containsKey 方法,它使用 get 方法来检查我的密钥是否已在映射中。下面是我的Hashmap.java类。