原文地址:http://blog.chinaunix.net/u1/53616/showart_432480.html
我们可以放基本变量或者自己定义的对象来进行key-->value的查找
我们先创建一个自己的类,作为hashmap的key
class key {
int i;
public key(int i) {
this.i = i;
}
}
class value {
int j;
public value(int j) {
this.j = j;
}
public String toString() {
return "" + j;
}
}
public class Test {
public static void main(String[] args) {
HashMap hm = new HashMap();
key k = new key(1); // ******(1)
value v = new value(2);
hm.put(k, v);
if (hm.containsKey(k)) // *********(2)
System.out.println(hm.get(k)); // *********(3)
else
System.out.println("dont have such a key");
}
}
注意,我这里的hashmap中的key是自己new出一个对象,然后把对象的引用作为key的,这里突出了hashmap的查找原理,hashmap是通过key的hashcode来找到hashmap中的key,这里我在hashmap的key中是放一个对象的应用,我去拿key的时候也是通过这个引用,所以(1)处的key 与(2)、(3)处的key是完全一样的,所以这段程序没有任何问题,顺利运行。
现在我把测试类改一下:
public class Test {
public static void main(String[] args) {
HashMap hm = new HashMap();
hm.put(new key(1), new value(2));
if (hm.containsKey(new key(1)))
System.out.println(hm.get(new key(1)));
else
System.out.println("dont have such a key");
}
}
注意区别,我这里hashmap中key放的不是引用,而是new出来的对象,然后我去get或者containsKey的时候也通过new一个key去拿,虽然我们初始化内容完全相同,都是放 int 1 进去,也就是说对象内容完全相同,但最后结果确实输出"dont have such a key"。
找原因,为什么内容相同,但找不到这个key呢,前面说了hashmap是通过hashcode来找key的位置,这是关键,你每次new 一个新对象出来hashcode肯定不一样,所以你拿不到你要的key。
解决方法,重写你编写的key类的hashcode方法。
class key {
int i;
public key(int i) {
this.i = i;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof key) {
if (((key) obj).i == i)
return true;
}
return false;
}
@Override
public int hashCode() {
return i;
}
}
我们先不要看equals的重写,这里我们重写了hashcode这个方法,让它返回一个我们初始化进去的i,这样你每次new一个对象,因为是通过hashcode找key,而你的hashcode有只是值i,所以只要i相等,你就可以找到你的key的地址,注意,只是找到你要的key的地址,但key是不是同一个key还不一定。
然后我们开始比较我们传来的寻找value的key和hashmap中的key是不是同一个key,如果是那就找到了value。
在未重写equals方法我们是继承了object的equals方法,那里的 equals是比较两个对象的内存地址,显然我们new了2个对象内存地址肯定不一样,所以我们还要重写equals这个方法,让重写后的equals方法来比较我们对象里特有的东西。
重写equals方法一般按照如下步骤:
1.先判断这两个比较的对象是不是同个类型,如果类型都不相同,肯定不相同;
2.如果类型相同,我们先要把Object向下转型到我们的类类型,然后比较自己类特有的变量,这里我只是比较了类里i值是否相同,如果相同,则表明两个对象是相同的(只是作为hashmap的key来说是相同的),这样就可拿到hashmap的value了。
总结:
hashmap中value的查找是通过 key 的 hashcode 来查找,所以对自己的对象必须重写 hashcode 通过 hashcode 找到对对象后会用 equals 比较你传入的对象和 hashmap 中的 key 对象是否相同,所以要重写 equals.
//*******************
现在我们开始造假
因为前面说了hashmap是通过hashcode来找到key的位置,然后通过equals来比较key内容是否相同
那我们就可以做一个其它的类,但hashcode和equals和前面的key这个类完全相同
class key1 {
int i;
public key1(int i) {
this.i = i;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof key) {
if (((key) obj).i == i)
return true;
}
return false;
}
@Override
public int hashCode() {
return i;
}
}
这样的话我在测试类Test中加上一句
public class Test {
public static void main(String[] args) {
HashMap hm = new HashMap();
hm.put(new key(1), new value(2));
hm.put(new key1(1), new value(22222222));
// ***这句是加的
if (hm.containsKey(new key(1)))
System.out.println(hm.get(new key(1)));
else
System.out.println("dont have such a key");
}
}
现在问题就来了,因为key1和key的hashcode定义都完全一样,就是说 new key(1) 和 new key1(1) 的hushcode完全一样,这样一来先定义的 new key(1) 就被后定义的 new key1(1) 覆盖了,但前面说了hashmap只是根据hashcode来找key位置,只要hushcode 一样就可以找到 key 的位置,所以我们是可以通过 new key(1) 来找到 new key1(1) 这个key的位置的,而且由于 key 类和 key1 类里的equals方法也一样,我们就可以用 new key(1)来假冒new key1(1) ,来拿到new key1(1) 对应的value值。
当然如果你想拿new value(2)这个value是肯定拿不到了
分享到:
相关推荐
总的来说,理解并正确地重写 `equals()` 和 `hashCode()` 方法是Java编程中的基础技能,它有助于确保对象的比较和集合操作的正确性。在开发过程中,要时刻注意这两个方法的正确实现,以提高代码质量和可维护性。
在Java编程中,`equals()` 和 `hashCode()` 方法是Object类中的两个重要方法,它们在处理对象相等性以及在哈希表(如HashSet、HashMap)中起到关键作用。当自定义类时,有时需要根据业务逻辑重写这两个方法以满足...
在Java编程语言中,`equals()` 和 `hashCode()` 方法是对象的基本组成部分,它们在很多场景下都发挥着至关重要的作用。这两个方法与对象的相等性比较和哈希表(如HashMap、HashSet)的运作紧密相关。这篇博客将深入...
例如,在Hashtable、HashMap、HashSet、LinkedHashMap等容器中,我们需要重写hashcode()方法,使其生成对象的哈希码,以便于快速地查找和比较对象。 compareTo()方法是Comparable接口中的一个方法,它用于比较两个...
在Java编程语言中,`hashCode()` 和 `equals()` 是两个非常重要的方法,它们主要用于对象的比较和哈希表(如HashMap)的操作。标题提到的"HashCode相同equals不同的2位字符集合算法"涉及到的是一个特定场景:两个...
为了解决这些问题,HashMap需要重写hashCode和equals方法,以确保两个不同的Key具有不同的哈希码和equals结果。同时,HashMap也需要处理哈希碰撞问题,例如使用链表来存储发生哈希碰撞的Key-Value对。 HashMap是一...
【面试】中提到的几个关键知识点集中在对象比较、equals()和hashCode()方法的使用以及它们之间的关系上。这些概念在Java编程中至关重要,特别是在处理集合类和比较对象时。 1、**hashCode与equals两者之间的关系**...
当我们在自定义类中重写 `equals()` 方法时,通常也需要重写 `hashCode()` 方法,这是为了遵循一些重要的原则和保证数据结构如 `HashMap`、`HashSet` 的正确行为。 首先,`equals()` 方法用于比较两个对象是否相等...
总之,重写 `equals` 和 `hashCode` 方法是保证自定义对象在集合中正确比较和存储的关键。这样做不仅可以满足特定的业务需求,还能确保集合操作的正确性和效率。在实现类时,应始终注意这两个方法的配合使用,以遵循...
在Java编程语言中,`equals()` 和 `hashCode()` 方法是对象的基本组成部分,它们与对象的比较和哈希表(如 `HashMap`)的操作密切相关。在面试中,面试官提出的问题直指这两个方法的重要关联。 首先,`equals()` ...
在Java编程语言中,`equals()` 和 `hashCode()` 方法对于对象的比较和处理至关重要,特别是在集合框架中。这两个方法有着紧密的联系,因为它们在决定对象是否相等以及如何存储和检索对象时起到关键作用。 首先,让...
在 TestEqualsHashCode.java 文件中,通常会包含一个示例,演示如何正确地重写 `equals()` 和 `hashCode()` 方法。这个文件可能包含一个自定义类,并展示如何根据类的属性定义这两个方法,以实现特定的比较逻辑。 ...
在Java编程语言中,序列化(Serialization)和重写`hashCode`及`equals`方法是两个重要的概念,它们各自有着特定的用途,并且在某些情况下相互关联。下面将详细阐述这两个概念及其应用。 首先,Java序列化是将一个...
3. **兼容数据结构**:许多Java集合框架中的数据结构(如HashSet、HashMap)依赖于对象的`equals`和`hashCode`方法来判断元素的唯一性。如果未正确重写`equals`方法,这些数据结构可能会出现异常行为。 #### 三、...
"Java重写equals及hashcode方法流程解析" Java中的equals和hashCode方法是两个非常重要的方法,它们都是Object...同时,我们还需要注意到,重写equals方法时,必须重写hashCode方法,以便于确保对象的正确性和一致性。
equals 方法和 hashCode 方法是 Java 语言中两个重要的方法,它们都是在 Object 类中定义的。equals 方法用于比较两个对象是否相等,而 hashCode 方法用于返回对象的哈希码。 在 Java 的 Object 类中,equals 方法...
在Java编程语言中,`hashCode()` 和 `equals()` 方法是两个非常重要的概念,尤其是在处理对象比较和哈希表(如 `HashMap` 或 `HashSet`)时。这两个方法来源于 `Object` 类,是所有Java类的基类,因此,每个自定义类...
在Java编程语言中,`equals()` 和 `hashCode()` 是两个非常重要的方法,它们主要用于比较对象的平等性以及在散列数据结构(如 `HashMap`、`HashSet` 等)中的对象定位。当我们创建自定义类时,有时需要根据业务需求...
"关于Object中equals方法和hashCode方法判断的分析" 在 Java 中,Object 类提供了两个重要的方法:equals 方法和 hashCode 方法。这两个方法都是用于比较两个对象是否相等的,但它们的实现机理和作用域却有所不同。...
在Java编程语言中,`hashCode()`和`equals()`方法是对象身份验证的关键组成部分,它们主要用于对象的比较和哈希表(如HashMap、HashSet等)的操作。理解这两个方法的工作原理对于编写高效和可靠的代码至关重要。 ...