1,hashCode值 和 对象的地址 二者的联系和区别 对于自定义类 当新建一个自定义类,它会继承hashCode方法。 当我们调用hashCode方法时,会返回一个int 数据?这个数据是怎么得来的了?它与很多内容 相关,与这个对象的内存地址,对象上的成员 变量等都有关,这些都参与了哈希值的运算。所以 可以明确的是:哈希值不是对象的地址。怎样判断 引用是否相同?其实是比较引用指向的地址是否 相同。 如果简单的认为hashCode返回的值是地址值,那么 覆盖此方法,使其返回值都相同,那么所有新建 的对象不是都相同吗?显然不是。 2,equals方法到底在比什么 很多地方都提到了 equals方法与 == 的区别 , == 这个操作符 是java固有的操作符,它的比较方式是固定的:基本类型数值比较, 引用类型比较。都有自己的规定和计算方法。 但是对于equals方法, 它是一个方法,所有类继承自Object类。由于重载的原因,使其成为 一个很灵活的比较方法,你可以按自己的想法去指定两个对象如何相等。 这时需要关心的是,查看谁的equals方法:谁调用查看谁,看它指定的 比较方式。 看下面一段代码: public class MyHashSet { public static void main(String args[]){ E element = new E(); E element2 = new E(); String str = new String("这不合逻辑!"); sop(element.hashCode()); sop(element2.hashCode()); sop(str.hashCode());//String 覆盖了hashCode方法,有自己计算哈希值的方法 sop(element == element2); sop(element.equals(element)); //sop(element == str);这句在编译时就无法通过。 sop(element.equals(str)); } public static void sop(Object obj){ System.out.println(obj); } } class E { public boolean equals(Object obj){ //你可以很不负责的让两个对象“相等” return true; } public int hashCode(){ return 60; } } ---------- 运行java程序 ---------- 60 60 -342913705 false true True 从运行结果来看:== 检查的是两个对象的地址值是否相同,对于不同类型在编译时就会出错。 而指定的equals方法,理论上可以使任何对象“相等”,不过这种相等并无实际意义。 有了以上内容做铺垫,我们在来看看HashSet是如何保证元素的唯一性,就比较清楚了。 你可以把HashSet集合看成是一个装东西的容器:玻璃瓶,罐子都行。只是在装入东西时,要按这个容器的规则进行。 当我们新建一个对象,以自定义对象为例。因为有hashCode方法,这个对象总会产生一个哈希值,不管你的自定义类覆盖hashCode方法与否。 当我们向HashSet容器放元素(或者对象,其实是对象的引用)时,元素放在哪是一个问题。HashSet这个集合的特点是,每个元素都有哈希值,依据元素的哈希值,决定存放位置。
|