关于这个问题,一般初中级面试中都会遇到,还记得我当初实习找工作的时候也遇到了这个问题,现在都还记得自己是怎么回答的:== 是基本类型比较,equals 是对象比较,不懂 hashCode,想起来简直惨不忍睹。于是找了一点小时间,研究了一番整理成文章供大家参考。

== 是什么?

在《java核心技术卷 1》中将 ==归类于关系运算符;

==常用于相同的基本数据类型之间的比较,也可用于相同类型的对象之间的比较;

  • 如果 ==比较的是基本数据类型,那么比较的是两个基本数据类型的值是否相等;

  • 如果 ==是比较的两个对象,那么比较的是两个对象的引用,也就是两个对象是否为同一个对象,并不是比较的对象的内容;

下面举例说明:

  1. public class Test {

  2. public static void main(String[] args){

  3. // 对象比较

  4. User userOne = new User();

  5. User userTwo = new User();

  6. System.out.println("userOne==userTwo : "+(userOne==userTwo));

  7. // 基本数据类型比较

  8. int a=1;

  9. int b=1;

  10. char c='a';

  11. char d='a';

  12. System.out.println("a==b : "+(a==b));

  13. System.out.println("c==d : "+(c==d));

  14. }

  15. }

实体类:

  1. class User {

  2. String userName;

  3. String password;

  4. }

运行结果:

  1. userOne==userTwo : false

  2. a==b : true

  3. c==d : true

对象 userOne 和 userTwo 虽然都是 User 的示例,但对于了堆内存的不同区域,因此他们的引用也不同,所以为 false;a 和 b 都是基本类型因此对比的是指,结果为 true ; c 和 d 也是基本类型 通 a 和 b.

equals 是什么鬼?

在《java核心技术卷 1》中对 Object 类的描述:Object 类是java中所有类的始祖,在java中每个类都是由Object类扩展而来;每个类都默认继承Object类,所以每一个类都有Object类中的方法;从而每一个类都有equals方法;

equals方法主要用于两个对象之间,检测一个对象是否等于另一个对象;

下边来看一看Object类中equals方法的源码:

  1. public boolean equals(Object obj) {

  2. return (this == obj);

  3. }

可以看出来Object类中的equals方法用的还是 ==,也就是比较的两个对象的引用是否相等,并不是根据对象中的属性来判断两个对象是否相等的;也就是说我们自己定义的类中,如果没有重写equals方法,实际上还是用的 ==来比较的两个对象,则用equals方法比较的结果与用==比较的结果是一样的;

java语言规范要求equals方法具有以下特性:

  • 自反性。对于任意不为null的引用值x,x.equals(x)一定是true。

  • 对称性)。对于任意不为null的引用值x和y,当且仅当x.equals(y)是true时,y.equals(x)也是true。

  • 传递性。对于任意不为null的引用值x、y和z,如果x.equals(y)是true,同时y.equals(z)是true,那么x.equals(z)一定是true。

  • 一致性。对于任意不为null的引用值x和y,如果用于equals比较的对象信息没有被修改的话,多次调用时x.equals(y)要么一致地返回true要么一致地返回false。

  • 对于任意不为null的引用值x,x.equals(null)返回false。

下面再来看一看比较典型的一个类;

  • String

这是jdk中的类,而且该类重写了equals方法;

下面来看一看该类中的equals方法源码:

  1. public boolean equals(Object anObject) {

  2. if (this == anObject) {

  3. return true;

  4. }

  5. if (anObject instanceof String) {

  6. String anotherString = (String)anObject;

  7. int n = value.length;

  8. if (n == anotherString.value.length) {

  9. char v1[] = value;

  10. char v2[] = anotherString.value;

  11. int i = 0;

  12. while (n-- != 0) {

  13. if (v1[i] != v2[i])

  14. return false;

  15. i++;

  16. }

  17. return true;

  18. }

  19. }

  20. return false;

  21. }

从源码可以看出equals方法是进行的内容比较;

举个例子:

  1. public class Test {

  2. public static void main(String[] args){

  3. // 未重写equals方法的类

  4. User userOne = new User();

  5. User userTwo = new User();

  6. System.out.println("userOne.equals(userTwo) : "+(userOne.equals(userTwo)));

  7. //重写了equals方法的类

  8. String a="1111";

  9. String b="1111";

  10. System.out.println("a.equals(b) : "+(a.equals(b)));

  11. }

  12. }

实体类:

  1. class User {

  2. String userName;

  3. String password;

  4. }

下面是运行结果:

  1. userOne.equals(userTwo) : false

  2. a.equals(b) : true

说明 String 对比的是对象的值。

hashCode 有什么作用?

hashCode也是 Object类中的方法;下面看一下 hashCode方法的源码:

  1. public native int hashCode();

该方法是一个本地方法;该方法返回对象的散列码(int类型);它的实现是根据本地机器相关的;

下面是百度百科对hash的说明:

Hash,一般翻译做散列、杂凑,或音译为哈希,是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来确定唯一的输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。

散列函数能使对一个数据序列的访问过程更加迅速有效,通过散列函数,数据元素将被更快地定位

  1. Java对于eqauls方法和hashCode方法是这样规定的:

  • 如果两个对象相同,那么它们的hashCode值一定要相同;

  • 如果两个对象的hashCode相同,它们并不一定相同。

  • equals()相等的两个对象,hashcode()一定相等;equals()不相等的两个对象,却并不能证明他们的hashcode()不相等。

什么地方使用hashCode?

Hashcode值主要用于基于散列的集合,如HashMap、HashSet、HashTable…等等;

这些集合都使用到了hashCode,想象一下,这些集合中存有大量的数据,假如有一万条,我们向其中插入或取出一条数据,插入时如何判断插入的数据已经存在?取出时如何取出相同的数据?难道一个一个去比较?这时候,hashCode就提现出它的价值了,大大的减少了处理时间;这个有点类似于MySQL的索引;

  1. 举例

  1. public class Test {

  2. public static void main(String[] args){

  3. //未重写hashCode的类

  4. User userOne = new User("aa","11");

  5. User userTwo = new User("aa","11");

  6. System.out.println(userOne.hashCode());

  7. System.out.println(userTwo.hashCode());

  8. //重写hashCode的类

  9. String a = new String("string");

  10. String b = new String("string");

  11. System.out.println(a.hashCode());

  12. System.out.println(b.hashCode());

  13. }

  14. }

实体类:

  1. class User {

  2. private String userName;

  3. private String password;

  4. public User(String userName, String password) {

  5. this.userName = userName;

  6. this.password = password;

  7. }

  8. }

运行结果:

  1. 752848266

  2. 815033865

  3. -891985903

  4. -891985903

根据结果可以看出:userOne 和 userTwo 的 hashCode 值不一致;a 和 b 的 hashCode 一致。

以上便是 == 和 equals 的区别,你都 Get 到了吗?


精彩回顾:

面试点:Java 中 hashCode() 和 equals() 的关系

容器连接[Docker 系列-7]

现如今的技术浪潮中,我们到底该做些什么?

强烈推荐:

《Java 极客技术》知识星球限时优惠,现在加入只需 50 元,仅限前 1000 名,机不可失时不再来。趁早行动吧!

https://t.zsxq.com/J6Em2nU

隆重介绍:

Java 极客技术公众号,是由一群热爱 Java 开发的技术人组建成立,专注分享原创、高质量的 Java 文章。如果您觉得我们的文章还不错,请帮忙赞赏、在看、转发支持,鼓励我们分享出更好的文章。

 

别傻傻不知道 == 和 equals 的区别【面试系列】的更多相关文章

  1. JS魔法堂:属性、特性,傻傻分不清楚

    一.前言 或许你和我一样都曾经被下面的代码所困扰 var el = document.getElementById('dummy'); el.hello = "test"; con ...

  2. OCA,OCP,OCM傻傻分不清?

    可能大家知道OCA.OCP.OCM的关系是一个比一个难考,一个比一个含金量高,但是你知道具体的考试科目.考试方式.就业形势区别吗?不知道的话这篇通俗易懂的文章会让你一目了然. 区别一:含金量 ■OCA ...

  3. Java:接口和抽象类,傻傻分不清楚?

    01. 来看网络上对接口的一番解释: 接口(英文:Interface),在 Java 编程语言中是一个抽象类型,是抽象方法的集合.一个类通过继承接口的方式,从而来继承接口的抽象方法. 兄弟们,你们怎么 ...

  4. [转帖]十分钟快速理解DPI和PPI,不再傻傻分不清!

    十分钟快速理解DPI和PPI,不再傻傻分不清! https://baijiahao.baidu.com/s?id=1605834796518990333&wfr=spider&for= ...

  5. Java 中 == 和 equals 的区别

    有一段时间,== 和 equals 的区别一直困扰着我.因为涉及到Java的内存机制,然而Java的内存机制又是比较抽象的东西,所以对那时候的我来说,实在是很难理解. == 和 equals 最大的区 ...

  6. 写这篇博客之前,我又忘了“==”和equals的区别。

    没错.嘟嘟又把==号和equals 的区别给忘掉了 ==号比较基本类型的时候比的是值,比较引用类型的时候比较的是地址.equals比较基本类型的时候.... 脑子里关于这道题的答案好模糊好没有安全感 ...

  7. 【华为敏捷/DevOps实践】7. 敏捷,DevOps,傻傻不分清楚【华为云技术分享】

    文:姚冬(华为云DevCloud首席技术布道师,资深DevOps与精益/敏捷专家,金融解决方案技术Leader,中国DevOpsDays社区核心组织者) 前言 敏捷是什么?DevOps是什么?两者有什 ...

  8. 傻傻分不清之 Cookie、Session、Token、JWT

    傻傻分不清之 Cookie.Session.Token.JWT 什么是认证(Authentication) 通俗地讲就是验证当前用户的身份,证明“你是你自己”(比如:你每天上下班打卡,都需要通过指纹打 ...

  9. 《面试经典系列》- 从底层理解==和equals的区别

    前言 在我们Java面试中,基础知识基本上比定会考核的点,而“==和equals的区别”则是面试官最喜欢.最经常问的问题. 但我们看了不少的文章.解释,总是一头雾水.一知半解的,往往很容忘记.今天,我 ...

随机推荐

  1. 安装使用 superset

    安装 superset 创建虚拟环境: python -m venv msuperset 激活虚拟环境: cd msuperset source bin/activate 安装 superset pi ...

  2. Asp.Net MVC强类型页面获取值几种方式

    方式一 (V:视图) @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="v ...

  3. java 微信自定义菜单 java微信接口开发 公众平台 SSM redis shiro 多数据源

    A 调用摄像头拍照,自定义裁剪编辑头像,头像图片色度调节B 集成代码生成器 [正反双向](单表.主表.明细表.树形表,快速开发利器)+快速表单构建器 freemaker模版技术 ,0个代码不用写,生成 ...

  4. Java实现QQ邮件发送

    首先我们需要两个jar包,点击下面即可下载这两个包: JavaMail mail.jar 1.4.5 JAF(版本 1.1.1) activation.jar 我们这里采用QQ邮箱发送邮件为例,代码如 ...

  5. i春秋四周年庆典狂欢丨价值6000元的Web安全课程免费送啦

    重磅好消息 i春秋四周年庆典狂欢 感恩回馈新老用户 5888元的Web安全线上提高班 988元的Web安全线上入门班 免费送啦 快来围观 活动详情 1.活动时间:6月17日—6月30日 2.活动规则: ...

  6. LeetCode学习_day1:原地算法

    原地算法:是一种使用小的,固定数量的额外之空间来转换资料的算法.当算法执行时,输入的资料通常会被要输出的部份覆盖掉. 范例:冒泡排序.选择排序.插入排序.希尔排序 (1)冒泡排序: 冒泡排序算法的原理 ...

  7. 从html富文本中提取纯文本

    其实从html富文本中提取纯文本很简单,富文本基本上是使用html标签给文本加上丰富多彩的样式. 所以只需要将富文本字符串中的“<.....>”标签剔除,即可得到纯文本.我们可以使用正则表 ...

  8. Mac启动MySQL

    启动MySQL服务 sudo /usr/local/Cellar/mysql//bin/mysql.server start 停止MySQL服务 sudo /usr/local/Cellar/mysq ...

  9. day09 作业

    简述定义函数的三种方式 空函数.无参函数.有参函数 简述函数的返回值 函数内部代码经过一系列的逻辑处理返回的结果 函数没有返回值,默认返回None 函数可以通过return返回出返回值 return可 ...

  10. JSP 与Javabean 的交互技术

    JSP 与Javabean 的交互技术 JavaBean的属性可以是任意类型,并且一个JavaBean可以有多个属性.每个属性通常都需要具有相应的setter. getter方法,setter方法称为 ...