本着针对面试,不负责任的态度,写下《面试总结》系列。本系列记录面试过程中各个知识点,而不是入门系列,如果有不懂的自行学习。
畅所欲言,欢迎来喷。
转载请标明出处,本文地址:https://www.jianshu.com/p/b7f28817bad1
面试中经常会问到这类问题。如下:
String s1="123";
String s2="123";
String s3=new String("123");
System.out.println(s1==s2);
System.out.println(s1==s3);
System.out.println(s1.equals(s2));
- 两个类对象的hashCode相等,对象相等吗?equals相等,对象相等吗?
以上两种算是一类问题。
首先,要说1中==操作的问题,对String赋值,而非new出来的对象,这类值通常会存放在常量池中,不会在堆中创建对象,所以s1与s2指向的是同一个地址。s3是new出来的,那么会在堆中创建对象,在s3指向的是堆中的地址,所以s1==s3比较的是地址。
其次,equals操作,由于String类中重写了equals方法,而Object类中的equals方法是直接做的==比较。
//Object.java
public boolean equals(Object obj) {
return (this == obj);
}
String类中重写了equals()方法
//String.java
public boolean equals(Object var1) {
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()判断的是对象的内容呢?
答案是不可以
,那么为什么呢?
==判断的是两个对象的地址,这个毋庸置疑,但是equals()这个是不确定的。
我们知道equals()方法是Object中的,也就是说,所有的对象都可以去覆盖重写该方法。没有重写equals()的时候,默认的equals()方法,等价于==方法。如果像String中那样,每个类都有自己的逻辑,自定义个类,重写equals()方法,恒返回true,那么怎么能够判断出来对象是相等呢?或者如学生类,重写equals()的时候,判断学生的姓名,年龄,性别,学号相等,那么返回true,这个也是符合自己的逻辑,但不能说明两个类对象是相等的。
hashCode跟equals又是什么关系
默认的Object中的hashCode()是用的native层,得到一个hash值。
public native int hashCode();
-
类没有重写hashCode方法,那么类对象equals比较的时候,跟hashCode没有任何关系。
-
重写了hashCode()方法。
a. equals相等的两个对象,hashCode()得到值一定相等
b. hashCode值相等的两个对象,equals不一定相等。
b)中的情况,可以从HashMap等使用hash值的集合中得到结果。当hash值相等的时候,说明发生了hash冲突。
重要的事情
在决定重写hashCode()方法的时候,一定要做到规范,有含义,不然如果在对象添加到HashMap等集合中发生冲突的概率会大大提高。
网友评论