• 概述

Java中,Object类是所有类的基类:如果一个类没有明确继承其他已定义的类,则默认继承Object类。

Object类提供了以下方法,对于其他方法,请参考前期专题描述。

hashCode()方法、equals()方法和”==“通常在进行对象比较的时候容易引起混淆。

对于 hashCode()方法、equals()方法而言,在使用的时候需要注意是否重写了该方法;String类重写了这两个方法,需要了解重写的内容。以下分别进行详细叙述。

  • hashCode()方法

在Object类中,hashCode()方法定义如下:

    public native int hashCode();

  该方法是native修饰的本地方法,返回一个描述该对象的int类型数据,也称为哈希码值。

Java没有提供相应实现类,由native接口调用相应的C++方法实现。方法实现可以参考openjdk相应C++代码。

JDK1.6API对该值的描述是:由 Object 类定义的 hashCode 方法会针对不同的对象返回不同的整数。一般是通过将该对象的内部地址转换成一个整数来实现的。

hashCode()方法的主要作用:为了提高访问哈希表(例如 java.util.Hashtable 提供的哈希表)的性能。

hashCode 方法的常规协定:

    1. 在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必定一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。程序多次执行,对象产生的hashCode可能是不同的。
    2. 如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。
    3. 如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法不要求一定生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。

总结以上三点:如果没有重写hashCode方法,对于同一个对象,在一个程序运行期间,所产生的hashCode是一样的。

  • equals()方法

该方法用于比较是否是同一个对象,其源代码如下所示:

    public boolean equals(Object obj) {
return (this == obj);
}

  

该方法中,使用“==”判断是否是同一个对象的引用,如果表示同一个对象,则返回true。

  • ==

“==”是java中的比较运算符。对于基本数据类型,比较的是值的大小是否相等;对于引用类型,比较的是内存地址是否一致。

  • String类的hashCode()方法和equals()方法

String类对这两个方法都进行了重写。

String类hashCode()方法代码如下,在字符串中,hashCode生成的方式发生了变化:hashCode的值依赖于字符串内容。

    public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value; for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}

String类equals()方法代码如下,重写的方法首先判断是否是同一个字符串对象,如果是,则返回true,如果不是,则对两个字符串对象的内容进行比较,完全一致则返回true。

 public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
  • String对象比较示例

示例代码:

		String str1 = new String("Hello");
String str2 = new String("Hello");
// 判断是否是同一个对象
System.out.println(str1 == str2);
// 判断字符串内容是否一致
System.out.println(str1.equals(str2));
// hashCode是否一致
System.out.println(str1.hashCode() + "," + str2.hashCode());
// System.identityHashCode()方法根据对象内存地址返回hashCode的值,不同对象的结果值必定是不同的
System.out.println(System.identityHashCode(str1) + "," + System.identityHashCode(str2));

  输出结果:

false
true
69609650,69609650
118352462,1550089733

  

由该例子可以看出,对于字符串类型数据,改写后的hashCode方法,如果字符串对象所代代表的内容一致,则返回相同的hashCode,这对于存储String是合理的。

Java使用散列集合存储对象,通过类似key的方式访问对象,可以认为key即是hashCode,对于字符串类型,如果字符串内容一致,则不需要进行重复存储,使用hashCode作为key方式访问字符串对象可以提高访问效率。否则使用用equals方法去遍历数据会降低程序效率。

JavaSE-28 hashCode()方法、equals()方法和==相关概念的更多相关文章

  1. Java 中正确使用 hashCode 和 equals 方法

    在这篇文章中,我将告诉大家我对hashCode和equals方法的理解.我将讨论他们的默认实现,以及如何正确的重写他们.我也将使用Apache Commons提供的工具包做一个实现. 目录: hash ...

  2. 为什么要重写hashcode和equals方法?初级程序员在面试中很少能说清楚。

    我在面试 Java初级开发的时候,经常会问:你有没有重写过hashcode方法?不少候选人直接说没写过.我就想,或许真的没写过,于是就再通过一个问题确认:你在用HashMap的时候,键(Key)部分, ...

  3. 【转】 如何重写hashCode()和equals()方法

    转自:http://blog.csdn.net/neosmith/article/details/17068365 hashCode()和equals()方法可以说是Java完全面向对象的一大特色.它 ...

  4. 如何重写hashCode()和equals()方法

    hashCode()和equals()方法可以说是Java完全面向对象的一大特色.它为我们的编程提供便利的同时也带来了很多危险.这篇文章我们就讨论一下如何正解理解和使用这2个方法. 如何重写equal ...

  5. 为什么要重写hashcode和equals方法

    我在面试 Java初级开发的时候,经常会问:你有没有重写过hashcode方法?不少候选人直接说没写过.我就想,或许真的没写过,于是就再通过一个问题确认:你在用HashMap的时候,键(Key)部分, ...

  6. 用HashSet的add方法谈hashcode和equals方法重写

    本文主要通过用HashSet的add方法讲一下hashCode和equals方法重写.错误的地方望指正. 1.了解HashSet的add方法 了解一个方法的好办法是看源码,所以先看源码 private ...

  7. 使用hashCode()和equals()方法 - Java

    在这篇文章中,我将指出我对hashCode()和equals()方法的理解.我将讨论它们的默认实现以及如何正确地覆盖它们.我还将使用Apache Commons包中的实用工具类来实现这些方法. has ...

  8. K:java中的hashCode和equals方法

      hashCode和equals方法是Object类的相关方法,而所有的类都是直接或间接的继承于Object类而存在的,为此,所有的类中都存在着hashCode和equals.通过翻看Object类 ...

  9. hashcode和equals方法的区别和联系

    说到 hashcode就要和Java中的集合,HashSet,HashMap 关系最为密切. 首先附录两张Java的集合结构图: 图二:(上图的简化版) 从Set集合的特点说起 & Set是如 ...

  10. (转)Java 中正确使用 hashCode 和 equals 方法

    背景:最近在编写持久化对象时候遇到重写equals和hashCode方法的情况,对这两个方法的重写做一个总结. 链接:https://www.oschina.net/question/82993_75 ...

随机推荐

  1. python的time模块使用

    在平常的代码中,我们常常需要与时间打交道.在Python中,与时间处理有关的模块就包括:time,datetime以及calendar.这篇文章,主要讲解time模块. 在开始之前,首先要说明这几点: ...

  2. 附加类型“UniversalReviewSystem.Models.ApplicationUser”的实体失败,因为相同类型的其他实体已具有相同的主键值。在使用 "Attach" 方法或者将实体的状态设置为 "Unchanged" 或 "Modified" 时如果图形中的任何实体具有冲突键值

    在使用asp.net Identity2 的 UserManager RoleManager 时,同时还有其他仓储类型接口,能实现用户扩展信息的修改,用户注册没有问题.当修改用户信息时,出现了如下异常 ...

  3. Logistic/Softmax Regression

    辅助函数 牛顿法介绍 %% Logistic Regression close all clear %%load data x = load('ex4x.dat'); y = load('ex4y.d ...

  4. A tutorial by example(转载)

    转自:http://mrbook.org/blog/tutorials/make/ Compiling your source code files can be tedious, specially ...

  5. poj1477(水)

    犯了一个错误,贡献了一次CE: G++里面没有头文件,用scanf会CE:然而C++就可以. 两大cow解释: 最好不要c 的输入和c++的一起用 (特别是关同步的时候) 然而好像他们也不是很了解.. ...

  6. 基于FBX SDK的FBX模型解析与加载 -(三)

    http://blog.csdn.net/bugrunner/article/details/7229416 6. 加载Camera和Light 在FBX模型中除了几何数据外较为常用的信息可能就是Ca ...

  7. bzoj 4530: [Bjoi2014]大融合【LCT】

    新姿势,一般来讲LCT只能维护splay重边里的数据,而这里要求维护整颗子树的size 多维护一个sq表示当前点轻儿子的size和,si表示包括轻重边的整颗子树的大小 然后需要改sq的地方是link和 ...

  8. 11.6NOIP模拟赛

    [数据规模和限制] 对于全部测试数据,满足 N,M,K≤,W≤ 各个测试点的数据规模及特殊性质如下表. 测试点 N M K ≤ ≤ ≤ ≤ ≤ ≤ ≤ ≤ ≤ ≤ 师 更多咨询:北京信息学窦老师 QQ ...

  9. android内存溢出 java.lang.OutOfMemoryError

    今天在做ListView 的时候.想做一个音乐列表模块,前面是图片,后面是分类名称,如下图: 结果运行时候,LogCat是总是报 java.lang.OutOfMemoryError的错误,顾名思义, ...

  10. 鸟哥私房菜基础篇:认识与学习BASH习题

    猫宁!!! 参考链接:http://linux.vbird.org/linux_basic/0320bash.php 鸟哥是为中国信息技术发展做出巨大贡献的人. 1-在 Linux 上可以找到哪些 s ...