关于这个问题,通常初中级面试中都会遇到,还记得我当初实习找工做的时候也遇到了这个问题,如今都还记得本身是怎么回答的:== 是基本类型比较,equals 是对象比较,不懂 hashCode,想起来简直惨不忍睹。因而找了一点小时间,研究了一番整理成文章供你们参考。java
在《java核心技术卷 1》中将==
归类于关系运算符;面试
==
经常使用于相同的基本数据类型之间的比较,也可用于相同类型的对象之间的比较;算法
==
比较的是基本数据类型,那么比较的是两个基本数据类型的值是否相等;==
是比较的两个对象,那么比较的是两个对象的引用,也就是两个对象是否为同一个对象,并非比较的对象的内容;下面举例说明:bash
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));
}
}
class User {
String userName;
String password;
}
运行结果:
userOne==userTwo : false
a==b : true
c==d : true
复制代码
对象 userOne 和 userTwo 虽然都是 User 的示例,但对于了堆内存的不一样区域,所以他们的引用也不一样,因此为 false;a 和 b 都是基本类型所以对比的是指,结果为 true ; c 和 d 也是基本类型 通 a 和 b.ide
在《java核心技术卷 1》中对 Object 类的描述:Object 类是java中全部类的始祖,在java中每一个类都是由Object类扩展而来;每一个类都默认继承Object类,因此每个类都有Object类中的方法;从而每个类都有equals方法;函数
equals方法主要用于两个对象之间,检测一个对象是否等于另外一个对象;ui
下边来看一看Object类中equals方法的源码:this
public boolean equals(Object obj) {
return (this == obj);
}
复制代码
能够看出来Object类中的equals方法用的仍是==
,也就是比较的两个对象的引用是否相等,并非根据对象中的属性来判断两个对象是否相等的;也就是说咱们本身定义的类中,若是没有重写equals方法,实际上仍是用的==
来比较的两个对象,则用equals方法比较的结果与用==比较的结果是同样的;spa
java语言规范要求equals方法具备如下特性:.net
下面再来看一看比较典型的一个类;
这是jdk中的类,并且该类重写了equals方法;
下面来看一看该类中的equals方法源码:
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;
}
复制代码
从源码能够看出equals方法是进行的内容比较;
举个例子:
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)));
}
}
class User {
String userName;
String password;
}
复制代码
下面是运行结果:
userOne.equals(userTwo) : false
a.equals(b) : true
复制代码
说明 String 对比的是对象的值。
hashCode
也是Object
类中的方法;下面看一下hashCode
方法的源码:
public native int hashCode();
复制代码
该方法是一个本地方法;该方法返回对象的散列码(int类型);它的实现是根据本地机器相关的;
下面是百度百科对hash的说明:
Hash,通常翻译作散列、杂凑,或音译为哈希,是把任意长度的输入(又叫作预映射pre-image)经过散列算法变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间一般远小于输入的空间,不一样的输入可能会散列成相同的输出,因此不可能从散列值来肯定惟一的输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。
散列函数能使对一个数据序列的访问过程更加迅速有效,经过散列函数,数据元素将被更快地定位
Hashcode值主要用于基于散列的集合,如HashMap、HashSet、HashTable…等等;
这些集合都使用到了hashCode,想象一下,这些集合中存有大量的数据,假若有一万条,咱们向其中插入或取出一条数据,插入时如何判断插入的数据已经存在?取出时如何取出相同的数据?难道一个一个去比较?这时候,hashCode就提现出它的价值了,大大的减小了处理时间;这个有点相似于MySQL的索引;
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());
}
}
class User {
private String userName;
private String password;
public User(String userName, String password) {
this.userName = userName;
this.password = password;
}
}
运行结果:
752848266
815033865
-891985903
-891985903
复制代码
根据结果能够看出:userOne 和 userTwo 的 hashCode 值不一致;a 和 b 的 hashCode 一致。
PS: 欢迎关注公众号 [ Java极客技术 ]
Java 极客技术公众号,是由一群热爱 Java 开发的技术人组建成立,专一分享原创、高质量的 Java 文章。若是您以为咱们的文章还不错,请帮忙赞扬、在看、转发支持,鼓励咱们分享出更好的文章。
参考文章:
Java中的equals()和hashcode()之间关系
HashCode的做用原理和实例解析
Guide to hashCode() in Java
equals() and hashCode() methods in Java