JAVA和Nginx 教程大全

网站首页 > 精选教程 正文

java 核心技术-12版 卷Ⅰ- 5.2.4 hashCode方法

wys521 2024-11-28 09:01:34 精选教程 50 ℃ 0 评论

原文

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。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表