快速掌握Java初中级面试中的 == 和 equals 的必问考题

<head>/<head><body>

在Java的初中级面试中,总有这么一题目它是那么的耀眼,那么坚强。它就是关于==和equals的区别是什么?这个题目相信很多小伙伴都已经遇到过了,下面我们在本篇中使用通俗的介绍让大家快速理解掌握。

== 是什么?

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

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

  • 如果==比较的是基本数据类型,那么比较的是两个基本数据类型的值是否相等;
  • 如果==是比较的两个对象,那么比较的是两个对象的引用,也就是两个对象是否为同一个对象,并不是比较的对象的内容;

下面举例说明:

public class Test {
public static void main(String[] args){
// 对象比较
User userOne = new User();
User userTwo = new User();
System.out.println("userOne==userTwo : "+(userOne==userTwo));
// 基本数据类型比较
int a=1;
int b=1;
char c='a';
char d='a';
System.out.println("a==b : "+(a==b));
System.out.println("c==d : "+(c==d));
}
}

运行结果:

userOne==userTwo : false
a==b : true
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方法的源码:

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

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

但是如果真的equals和==是一样的,还有存在的必要吗?

快速掌握Java初中级面试中的 == 和 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。

既然java语言规范针对equals有那么多要求,显而易见,是想让我们自己进行重写的呢。

那么怎么重写呢?

快速掌握Java初中级面试中的 == 和 equals 的必问考题

我们直接来看一下Java官方已经重写的一个类,那就是String类。

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类已经重写了equals方法,那么String就会根据其重写的规则进行内容比较。下面我们再来举个例子来看一下重写equals方法后的String有什么不同。

例子2 :

public class Test {
public static void main(String[] args){
// 未重写equals方法的类
User userOne = new User();
User userTwo = new User();
System.out.println("userOne.equals(userTwo) : "+(userOne.equals(userTwo)));
//重写了equals方法的类
String a="1111";

String b="1111";
System.out.println("a.equals(b) : "+(a.equals(b)));
}
}

测试结果:

userOne.equals(userTwo) : false
a.equals(b) : true

结论 : 虽然String是一个对象不是基本类型,但是由于String重写了equals方法,所以仍然比较的值类型。

hashCode 又是什么东西呢?

我们经常听说在重写完毕equals后就需要重写hashCode方法,这是我们经常听到的,但是很多小伙伴不知道为什么。

hashCode也是Object类中的方法;下面看一下hashCode方法的源码。该方法是一个本地方法;该方法返回对象的散列码(int类型);它的实现是根据本地机器相关的。

public native int hashCode();

那么这个方法返回的散列码有什么用呢?平时开发的时候也没有注意到这个散列码啊?

快速掌握Java初中级面试中的 == 和 equals 的必问考题

其实呢,这个问题很简单,hashCode的散列码在Java语言中是非常重要的。设想,如果你需要插入100个对象中到一个Set集合中,那么在插入数据的时候肯定要和已经插入的数据进行比较是否相等,如果相等则不插入。(因为Set不允许重复嘛)。既然需要用到比较,那么是调用equals进行比较吗?不不不,当然不是,那样效率该有多慢啊!

Java在将一个对象插入的集合中的时候,首先会调用该对象的hashCode方法获取散列码,将该散列码与已经插入的对象的散列码进行比较,如果没有相同的散列码,就说明没有重复的。如果有相同的散列码,则说明已经存在对象在该散列码的hash链上,就会将相同散列码的对象调用equals进行内容比较。

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

  • 如果两个对象相同,那么它们的hashCode值一定要相同;
  • 如果两个对象的hashCode相同,它们并不一定相同。
  • equals()相等的两个对象,hashcode()一定相等;equals()不相等的两个对象,却并不能证明他们的hashcode()不相等。

例子 3:

public class Test {
public static void main(String[] args){
//未重写hashCode的类
User userOne = new User("aa","11");
User userTwo = new User("aa","11");
System.out.println(userOne.hashCode());
System.out.println(userTwo.hashCode());
//重写hashCode的类
String a = new String("string");
String b = new String("string");
System.out.println(a.hashCode());
System.out.println(b.hashCode());
}
}

测试结果 :

752848266 815033865 -891985903 -891985903

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

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


你喜欢关于IT面试求职的相关内容吗? (单选)
0人
0%
我很喜欢,请及时更新相关内容
0人
0%
我会留意,在我需要的时候
0人
0%
不感兴趣
<button>投票/<button>


/<body>


分享到:


相關文章: