JavaSE-28 hashCode()方法、equals()方法和==相关概念
- 概述
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 方法的常规协定:
- 在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必定一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。程序多次执行,对象产生的hashCode可能是不同的。
- 如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。
- 如果根据 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()方法和==相关概念的更多相关文章
- Java 中正确使用 hashCode 和 equals 方法
在这篇文章中,我将告诉大家我对hashCode和equals方法的理解.我将讨论他们的默认实现,以及如何正确的重写他们.我也将使用Apache Commons提供的工具包做一个实现. 目录: hash ...
- 为什么要重写hashcode和equals方法?初级程序员在面试中很少能说清楚。
我在面试 Java初级开发的时候,经常会问:你有没有重写过hashcode方法?不少候选人直接说没写过.我就想,或许真的没写过,于是就再通过一个问题确认:你在用HashMap的时候,键(Key)部分, ...
- 【转】 如何重写hashCode()和equals()方法
转自:http://blog.csdn.net/neosmith/article/details/17068365 hashCode()和equals()方法可以说是Java完全面向对象的一大特色.它 ...
- 如何重写hashCode()和equals()方法
hashCode()和equals()方法可以说是Java完全面向对象的一大特色.它为我们的编程提供便利的同时也带来了很多危险.这篇文章我们就讨论一下如何正解理解和使用这2个方法. 如何重写equal ...
- 为什么要重写hashcode和equals方法
我在面试 Java初级开发的时候,经常会问:你有没有重写过hashcode方法?不少候选人直接说没写过.我就想,或许真的没写过,于是就再通过一个问题确认:你在用HashMap的时候,键(Key)部分, ...
- 用HashSet的add方法谈hashcode和equals方法重写
本文主要通过用HashSet的add方法讲一下hashCode和equals方法重写.错误的地方望指正. 1.了解HashSet的add方法 了解一个方法的好办法是看源码,所以先看源码 private ...
- 使用hashCode()和equals()方法 - Java
在这篇文章中,我将指出我对hashCode()和equals()方法的理解.我将讨论它们的默认实现以及如何正确地覆盖它们.我还将使用Apache Commons包中的实用工具类来实现这些方法. has ...
- K:java中的hashCode和equals方法
hashCode和equals方法是Object类的相关方法,而所有的类都是直接或间接的继承于Object类而存在的,为此,所有的类中都存在着hashCode和equals.通过翻看Object类 ...
- hashcode和equals方法的区别和联系
说到 hashcode就要和Java中的集合,HashSet,HashMap 关系最为密切. 首先附录两张Java的集合结构图: 图二:(上图的简化版) 从Set集合的特点说起 & Set是如 ...
- (转)Java 中正确使用 hashCode 和 equals 方法
背景:最近在编写持久化对象时候遇到重写equals和hashCode方法的情况,对这两个方法的重写做一个总结. 链接:https://www.oschina.net/question/82993_75 ...
随机推荐
- Codechef WEASELTX
WEASELTX code给你一棵 n 个节点的有根树(节点),以及每个节点 i 的初始权值 a[i] .一次操作则是指将每个节点的权值变为以其为根的子树中所有节点的权值之异或和.维护 q 个询问,每 ...
- Prepare for Mac App Store Submission--为提交到Mac 应用商店做准备
返回 Mac App Store Prepare for Mac App Store Submission 提交到Mac 应用商店之前的准备 Most of your time is spent on ...
- LXD安装
#安装 #初始化(一路next) sudo lxd init #启动容器 lxc launch ubuntu:16.04 first #进到容器内 lxc exec first -- /bin/bas ...
- ASP.NET Core MVC 2.x 全面教程_ASP.NET Core MVC 17. 基于Claim和Policy的授权 上
首先补一下昨天没有讲的东西 只有管理员才能访问UserController RoleController都加上这个角色 Cliam 不是管理员角色的用户访问 cliam是name个Value值的键值对 ...
- 任务26:dotnet watch run 和attach到进程调试
任务26:dotnet watch run 和attach到进程调试 dotnet watch run 的一种调试方法 打开VSCode,先关闭当前的文件夹 Ctrl+~快捷键 打开窗体. ls应该是 ...
- angular源码剖析之Provider系列--QProvider
QProvider 简介 源码里是这么描述的: A service that helps you run functions asynchronously, and use their return ...
- HDU2438:Turn the corner(三分)
传送门 分析 根据这张图,我们只要使得h<=y即可,可以发现h是一个凸函数,故使用三分,具体见代码 代码 #include<cstdio> #include<cstring&g ...
- js 切割逗号
使用string对象的split()方法可以处理.例如:var yourString=“12,25,24,234,234,”;var result=yourString.split(",&q ...
- c++模板专门化
#include <iostream> #include<cstring> using namespace std; template <typename T> T ...
- Hdu 5496 Beauty of Sequence (组合数)
题目链接: Hdu 5496 Beauty of Sequence 题目描述: 一个整数序列,除去连续的相同数字(保留一个)后,序列的和成为完美序列和.问:一个整数序列的所有子序列的完美序列和? 解题 ...