网站外链建设工作计划建站合作
news/
2025/9/26 18:02:52/
文章来源:
网站外链建设工作计划,建站合作,一个空间可以做多个网站吗,中外商贸网站建设平台第3部分 hashCode() 的作用
hashCode() 的作用是获取哈希码#xff0c;也称为散列码#xff1b;它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。
hashCode() 定义在JDK的Object.java中#xff0c;这就意味着Java中的任何类都包含有hashCo…第3部分 hashCode() 的作用
hashCode() 的作用是获取哈希码也称为散列码它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。
hashCode() 定义在JDK的Object.java中这就意味着Java中的任何类都包含有hashCode() 函数。 虽然每个Java类都包含hashCode() 函数。但是仅仅当创建并某个“类的散列表”(关于“散列表”见下面说明)时该类的hashCode() 才有用(作用是确定该类的每一个对象在散列表中的位置其它情况下(例如创建类的单个对象或者创建类的对象数组等等)类的hashCode() 没有作用。 上面的散列表指的是Java集合中本质是散列表的类如HashMapHashtableHashSet。 也就是说hashCode() 在散列表中才有用在其它情况下没用。在散列表中hashCode() 的作用是获取对象的散列码进而确定该对象在散列表中的位置。 OK至此我们搞清楚了hashCode()的作用是获取散列码。但是散列码是用来干什么的呢为什么散列表需要散列码呢要解决这些问题就需要理解散列表关于散列表的内容非三言两语道的明白大家可以通过下面几篇文章来学习
[转载] 散列表(Hash Table)从理论到实用上
[转载] 散列表(Hash Table)从理论到实用中
[转载] 散列表(Hash Table)从理论到实用下 为了能理解后面的内容这里简单的介绍一下散列码的作用。
我们都知道散列表存储的是键值对(key-value)它的特点是能根据“键”快速的检索出对应的“值”。这其中就利用到了散列码
散列表的本质是通过数组实现的。当我们要获取散列表中的某个“值”时实际上是要获取数组中的某个位置的元素。而数组的位置就是通过“键”来获取的更进一步说数组的位置是通过“键”对应的散列码计算得到的。
下面我们以HashSet为例来深入说明hashCode()的作用。 假设HashSet中已经有1000个元素。当插入第1001个元素时需要怎么处理因为HashSet是Set集合它允许有重复元素。 “将第1001个元素逐个的和前面1000个元素进行比较”显然这个效率是相等低下的。散列表很好的解决了这个问题它根据元素的散列码计算出元素在散列表中的位置然后将元素插入该位置即可。对于相同的元素自然是只保存了一个。 由此可知若两个元素相等它们的散列码一定相等但反过来确不一定。在散列表中 1、如果两个对象相等那么它们的hashCode()值一定要相同 2、如果两个对象hashCode()相等它们并不一定相等。 注意这是在散列表中的情况。在非散列表中一定如此
对“hashCode()的作用”就谈这么多。
第4部分 hashCode() 和 equals() 的关系
接下面我们讨论另外一个话题。网上很多文章将 hashCode() 和 equals 关联起来有的讲的不透彻有误导读者的嫌疑。在这里我自己梳理了一下 “hashCode() 和 equals()的关系”。
我们以“类的用途”来将“hashCode() 和 equals()的关系”分2种情况来说明。 1. 第一种 不会创建“类对应的散列表” 这里所说的“不会创建类对应的散列表”是说我们不会在HashSet, Hashtable, HashMap等等这些本质是散列表的数据结构中用到该类。例如不会创建该类的HashSet集合。 在这种情况下该类的“hashCode() 和 equals() ”没有半毛钱关系的 这种情况下equals() 用来比较该类的两个对象是否相等。而hashCode() 则根本没有任何作用所以不用理会hashCode()。
下面我们通过示例查看类的两个对象相等 以及 不等时hashCode()的取值。
源码如下 (NormalHashCodeTest.java)
import java.util.*;
import java.lang.Comparable;/*** desc 比较equals() 返回true 以及 返回false时 hashCode()的值。** author skywang* emai kuiwu-wang163.com*/
public class NormalHashCodeTest{public static void main(String[] args) {// 新建2个相同内容的Person对象// 再用equals比较它们是否相等Person p1 new Person(eee, 100);Person p2 new Person(eee, 100);Person p3 new Person(aaa, 200);System.out.printf(p1.equals(p2) : %s; p1(%d) p2(%d)\n, p1.equals(p2), p1.hashCode(), p2.hashCode());System.out.printf(p1.equals(p3) : %s; p1(%d) p3(%d)\n, p1.equals(p3), p1.hashCode(), p3.hashCode());}/*** desc Person类。*/private static class Person {int age;String name;public Person(String name, int age) {this.name name;this.age age;}public String toString() {return name - age;}/** * desc 覆盖equals方法 */ public boolean equals(Object obj){ if(obj null){ return false; } //如果是同一个对象返回true反之返回false if(this obj){ return true; } //判断是否类型相同 if(this.getClass() ! obj.getClass()){ return false; } Person person (Person)obj; return name.equals(person.name) ageperson.age; } }
}
运行结果
p1.equals(p2) : true; p1(1169863946) p2(1901116749)
p1.equals(p3) : false; p1(1169863946) p3(2131949076)
从结果也可以看出p1和p2相等的情况下hashCode()也不一定相等。
2. 第二种 会创建“类对应的散列表” 这里所说的“会创建类对应的散列表”是说我们会在HashSet, Hashtable, HashMap等等这些本质是散列表的数据结构中用到该类。例如会创建该类的HashSet集合。 在这种情况下该类的“hashCode() 和 equals() ”是有关系的 1)、如果两个对象相等那么它们的hashCode()值一定相同。 这里的相等是指通过equals()比较两个对象时返回true。 2)、如果两个对象hashCode()相等它们并不一定相等。 因为在散列表中hashCode()相等即两个键值对的哈希值相等。然而哈希值相等并不一定能得出键值对相等。补充说一句“两个不同的键值对哈希值相等”这就是哈希冲突。 此外在这种情况下。若要判断两个对象是否相等除了要覆盖equals()之外也要覆盖hashCode()函数。否则equals()无效。 例如创建Person类的HashSet集合必须同时覆盖Person类的equals() 和 hashCode()方法。 如果单单只是覆盖equals()方法。我们会发现equals()方法没有达到我们想要的效果。
参考代码 (ConflictHashCodeTest1.java)
import java.util.*;
import java.lang.Comparable;/*** desc 比较equals() 返回true 以及 返回false时 hashCode()的值。** author skywang* emai kuiwu-wang163.com*/
public class ConflictHashCodeTest1{public static void main(String[] args) {// 新建Person对象Person p1 new Person(eee, 100);Person p2 new Person(eee, 100);Person p3 new Person(aaa, 200);// 新建HashSet对象 HashSet set new HashSet();set.add(p1);set.add(p2);set.add(p3);// 比较p1 和 p2 并打印它们的hashCode()System.out.printf(p1.equals(p2) : %s; p1(%d) p2(%d)\n, p1.equals(p2), p1.hashCode(), p2.hashCode());// 打印setSystem.out.printf(set:%s\n, set);}/*** desc Person类。*/private static class Person {int age;String name;public Person(String name, int age) {this.name name;this.age age;}public String toString() {return (name , age);}/** * desc 覆盖equals方法 */ Overridepublic boolean equals(Object obj){ if(obj null){ return false; } //如果是同一个对象返回true反之返回false if(this obj){ return true; } //判断是否类型相同 if(this.getClass() ! obj.getClass()){ return false; } Person person (Person)obj; return name.equals(person.name) ageperson.age; } }
}
运行结果
p1.equals(p2) : true; p1(1169863946) p2(1690552137)
set:[(eee, 100), (eee, 100), (aaa, 200)]
结果分析 我们重写了Person的equals()。但是很奇怪的发现HashSet中仍然有重复元素p1 和 p2。为什么会出现这种情况呢 这是因为虽然p1 和 p2的内容相等但是它们的hashCode()不等所以HashSet在添加p1和p2的时候认为它们不相等。 下面我们同时覆盖equals() 和 hashCode()方法。
参考代码 (ConflictHashCodeTest2.java)
import java.util.*;
import java.lang.Comparable;/*** desc 比较equals() 返回true 以及 返回false时 hashCode()的值。** author skywang* emai kuiwu-wang163.com*/
public class ConflictHashCodeTest2{public static void main(String[] args) {// 新建Person对象Person p1 new Person(eee, 100);Person p2 new Person(eee, 100);Person p3 new Person(aaa, 200);Person p4 new Person(EEE, 100);// 新建HashSet对象 HashSet set new HashSet();set.add(p1);set.add(p2);set.add(p3);// 比较p1 和 p2 并打印它们的hashCode()System.out.printf(p1.equals(p2) : %s; p1(%d) p2(%d)\n, p1.equals(p2), p1.hashCode(), p2.hashCode());// 比较p1 和 p4 并打印它们的hashCode()System.out.printf(p1.equals(p4) : %s; p1(%d) p4(%d)\n, p1.equals(p4), p1.hashCode(), p4.hashCode());// 打印setSystem.out.printf(set:%s\n, set);}/*** desc Person类。*/private static class Person {int age;String name;public Person(String name, int age) {this.name name;this.age age;}public String toString() {return name - age;}/** * desc重写hashCode */ Overridepublic int hashCode(){ int nameHash name.toUpperCase().hashCode();return nameHash ^ age;}/** * desc 覆盖equals方法 */ Overridepublic boolean equals(Object obj){ if(obj null){ return false; } //如果是同一个对象返回true反之返回false if(this obj){ return true; } //判断是否类型相同 if(this.getClass() ! obj.getClass()){ return false; } Person person (Person)obj; return name.equals(person.name) ageperson.age; } }
}
运行结果
p1.equals(p2) : true; p1(68545) p2(68545)
p1.equals(p4) : false; p1(68545) p4(68545)
set:[aaa - 200, eee - 100]
结果分析 这下equals()生效了HashSet中没有重复元素。 比较p1和p2我们发现它们的hashCode()相等通过equals()比较它们也返回true。所以p1和p2被视为相等。 比较p1和p4我们发现虽然它们的hashCode()相等但是通过equals()比较它们返回false。所以p1和p4被视为不相等。
转发:https://www.cnblogs.com/skywang12345/p/3324958.html
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/916954.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!