网站首页 > 精选教程 正文
原文
5.2.4 hashCode方法
散列码(hash code)是由对象导出的一个整型值。散列码是没有规律的。如果x和y两个不同的对象,那么x.hashode() 与y.hashCode() 基本上不会相同。表 5-1 中列出了通过用String类的 hashCode 方法得到的几个散列码示例。
表5-1 hashode 方法得到的散列码
字符串 散列码
Hello 69689659
Harry 69496448
Heciker -2141031596
String类使用以下算法计算散列码:
int hash = 0:
for (int i = 0; i < length(); i++)
hash = 31 * hash + charAt(i);
由于hashCode 方法定义在 Object 类中,因此每个对象都有一个默认的散列码,其值由对象的存储地址得出。来看下面这个例子:
var s ="Gk* ;
var sb = new StringByilder(s);
Systen.out.println(s.hashCode() + " "+ sb.hashCode());
ver t = ned String("OK");
var tb = ne StringBuilder(t);
Systen.out.println(t.hashCode() +" "+ tb.hashCode());
表5-2列出了结果。
表5-2 字符串和字符串构建器的散列码
对象 散列码
s 2556
sb 20526976
t 2556
tb 20527144
请注意,字符串s与t有相同的散列码,这是因为字符串的散列码是由内容导出的。而字符串构建器 sb与 tb 却有着不同的散列码,因为在StringBuilder类中没有定义 hashCode方法,而 Object 类的默认 hashCode 方法会从对象的存储地址得出散列码。
如果重新定义了equals方法,还必须为用户可能插人散列表的对象重新定义 hashCode方法(有关散列表的内容将在第 9章中讨论)。
hashCode 方法应该返回一个整数(可以是负数)。要合理地组合实例字段的散列码,使得不同对象的散列码尽量分散开。
例如,下面是 Employee 类的 hashCode 方法:
public class Employee{
public int hashCode(){
return 7 * name.hashCode()
+ 11* Double.value0f(salary).hashCode()
+ 13 * hireDay.hashCode();
}
}
不过,还可以做得更好。首先,最好使用 null 安全的方法 Objects.hashCode。如果其参数为 null,则这个方法会返回 0;否则,返回对参数调用 hashCode 的结果。另外,可以使用静态方法 Double.hashCode 来避免创建 Double 对象:
public class Employee{
public int hashCode(){
return 7 * Objects.hashCode(name)
+ 11* Double.hashCode(salary)
+ 13 * Objects.hashCode(hireDay) ;
}
}
还有更好的做法是,需要组合多个散列值时,可以调用 Objects.hash 并提供所有这些值作为参数。这个方法会对各个参数调用 Objects.hashCode,并组合这些散列值。这样,Employee.
hashCode 方法可以简单地写为:
public int hashCode(){
return Objects.hash(name,salary, hireDay);
}
equals与 hashCode 的定义必须相容: 如果x.equals(y) 返回 true,那么x.hashCode() 就必须返回与 y.hashCode() 相同的值。例如,如果定义 Employee.equals 来比较员工的ID,那么hashCode 方法就需要对ID 计算散列值,而不考虑员工姓名或存储地址。
提示: 如果有数组类型的字段,那么可以使用静态的 Arrays.hashCode 方法计算一个散列码,这个散列码由数组元素的散列码组成。
注释:record类型会自动提供一个 hashCode 方法,它会由字段值的散列码得出一个散列码。
警告:如果实例变量的取值范围很小,那么你需要得到尽可能不同的散列码。考虑对日历日期计算散列码。如果计算7*year + 11*month +13* day,这会产生很多冲突。相比之下,31*12*year +31* month + day 则是一个“完美的散列函数”。假设有一个合理的年份范围,任意两个日期都不会有相同的散列码 (LocalDate 类实际的 hashCode 方法支持 正负999 999 999 范围内的年份,这个方法更为复杂)。
API : java.lang.Object JDK1.0
- int hashCode()
返回对象的散列码。散列码可以是任意的整数,包括正数或负数。两个相等的对象要求返回相同的散列码。
java.util.Objects JDK7
- static int hash(Object... objects)
返回散列码,由提供的所有对象的散列码组合得到
- static int hashCode(Object a)
如果a为 null,返回0;否则,返回a.hashCode()。
- java.lang.(Integer l Long I Short l Byte l Double l Float I Character l Boolean) JDK1.0
- static int hashCode(xxx value) JDK8
返回给定值的散列码。这里xxx 是对应给定包装器类型的基本类型。
java.util.Arrays JDK1.2
- static int hashCode(xxxl] a) JDK5
计算数组 a的散列码。这个数组的元素类型xxx 可以是 Object、int、long、short、char
byte、boolean、float或 double。
- 上一篇: Java入门书单
- 下一篇: 深入浅出Rust异步编程之Tokio
猜你喜欢
- 2024-11-28 java 核心技术-12版 卷Ⅰ- 5.2.3相等测试与继承
- 2024-11-28 Java入门书单
- 2024-11-28 java 核心技术-12版 卷Ⅰ- 4.3.7 隐式参数与显式参数
- 2024-11-28 全网最完整的免费java教程讲义系列(四)——java的流程控制
- 2024-11-28 java 核心技术-12版 卷Ⅰ- 4.6 对象构造 4.6.1重载
- 2024-11-28 java 核心技术-12版 卷Ⅰ- 3.10 数组
- 2024-11-28 java 核心技术-12版 卷Ⅰ- 4.3 自定义类
- 2024-11-28 2019年Java核心技术我整理了200多页pdf,今天分享给你
- 2024-11-28 java 核心技术12版卷1 - 1.3 Java applet 与 Internet
- 2024-11-28 java 核心技术-12版 卷Ⅰ- 4.2 使用预定义类
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)