asp语言的网站建设,网站开发和程序开发的却别,南郊网站建设报价,做网站直接从网上的icon吗在我们平时编写Java代码时#xff0c;重写equals方法时一定要重写hashCode方法#xff0c;这是为什么呢#xff1f;
在讨论这个问题前#xff0c;我们先看下Object类中hashCode方法和equals方法。
hashCode方法#xff1a; 翻译如下#xff1a; equals方法#xff1a;…在我们平时编写Java代码时重写equals方法时一定要重写hashCode方法这是为什么呢
在讨论这个问题前我们先看下Object类中hashCode方法和equals方法。
hashCode方法 翻译如下 equals方法 翻译如下 1、hashCode方法的作用
在Java中也一样hashCode方法的主要作用是为了配合基于散列的集合一起正常运行这样的散列集合包括HashSet、HashMap以及HashTable。
为什么这么说呢考虑一种情况当向集合中插入对象时如何判别在集合中是否已经存在该对象了
也许大多数人都会想到调用equals方法来逐个进行比较这个方法确实可行。但是如果集合中已经存在一万条数据或者更多的数据如果采用equals方法去逐一比较效率必然是一个问题。
此时hashCode方法的作用就体现出来了当集合要添加新的对象时先调用这个对象的hashCode方法得到对应的hashcode值实际上在HashMap的具体实现中会用一个table保存已经存进去的对象的hashcode值如果table中没有该hashcode值它就可以直接存进去不用再进行任何比较了如果存在该hashcode值 就调用它的equals方法与新元素进行比较相同的话就不存了不相同就散列其它的地址所以这里存在一个冲突解决的问题这样一来实际调用equals方法的次数就大大降低了说通俗一点Java中的hashCode方法就是根据一定的规则将与对象相关的信息比如对象的存储地址对象的字段等映射成一个数值这个数值称作为散列值。
java.util.HashMap的中put方法的具体实现先计算key的hash值从table数组中取出对应节点如果节点不存在则添加一个节点如果存在则更新value返回旧value。 hash方法会调用对象的hashCode()方法 addEntry方法添加新节点 new一个Entry实例next指向原有的Entry实例。也就是新new的Entry实例是该链表的头。 Entry是一个静态内部类有一个属性next指向下一个Entry形成一个链表结构。 2、equals方法和hashCode方法
看下面代码 输出结果 我们Student类重写了equals方法hashCode方法没有重写s1和s2的姓名和年龄相同equals方法为true认为是同一个人。但是s1和s2的hashCode返回不同。
我们看下hashMap的get方法先获取key的hashCode由于s1和s2的hashCode不同所以hashMap.get(s2)得到的是null。 接下来我们重写下Student类的hashCode方法让equals方法和hashCode方法始终在逻辑上保持一致性。 重新运行输出结果如下s1和s2的hashCode相同了hashMap.get(s2)得到了1。 ① 在 Java 应用程序执行期间在对同一对象多次调用 hashCode 方法时必须一致地返回相同的整数前提是将对象进行 equals 比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行该整数无需保持一致。
② 如果根据 equals(Object) 方法两个对象是相等的那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。
③ 如果根据 equals(java.lang.Object) 方法两个对象不相等那么对这两个对象中的任一对象上调用 hashCode 方法不 要求一定生成不同的整数结果。但是程序员应该意识到为不相等的对象生成不同整数结果可以提高哈希表的性能。
如果hashCode方法依赖于对象中易变的数据用户就要当心了因为此数据发生变化时hashCode()方法就会生成一个不同的hash值。看下面例子 修改了age属性的值导致hashCode变化所以输出为“null”。
因此在设计hashCode方法和equals方法的时候如果对象中的数据易变则最好在equals方法和hashCode方法中不要依赖于该字段。