==和equals的区别:
值类型是存储在内存中的堆栈(以后简称栈),而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中。
==操作比较的是两个变量的值是否相等,对于引用型变量表示的是栈中的内容是否相同。equals操作表示的两个变量是否是对同一个对象的引用,即堆中的内容是否相同。
总结:==比较的是2个对象的内存地址,而equals需要去比较的是2个对象的内容;
补充:
- 八种基本数据类型(整数:byte,short,int,long,字符:char,小数:double,float,布尔:boolean)没有equals方法,只有其对应的封装类(如:Integer,Character,Double)才能调用equals。
- 未重写equals的类,继承的是Object的equals方法,源码中是
public boolean equals(Object obj) { return (this == obj); }与 ’==‘是等价的,所以有下面的一个示例。
String a="string";
String b="string";
String c=new String("string");
String d=new String("string");
/*
a==b:::::::::::true
a==c:::::::::::false
a.equals(c):::::::::::true
c==d:::::::::::false
c.equals(d):::::::::::true
* */
class thisIsClass {
private Integer i;
thisIsClass(int i){
this.i=i;
}
@Override
public boolean equals(Object object){
if(object instanceof thisIsClass){
thisIsClass c= (thisIsClass) object;
return i.equals(c.i);
}
return false;
}
}
thisIsClass thisIsClass1=new thisIsClass(1);
thisIsClass thisIsClass2=new thisIsClass(1);
/**
* thisIsClass1==thisIsClass2:::::::::::false
* thisIsClass1.equals(thisIsClass2):::::::::::true 未重写thisIsClass的equals时,这个方法返回为false
*/
类型比较参考:https://www.cnblogs.com/pop822/p/6215040.html
equals和hashCode之间的关系
1、相等(相同)的对象必须具有相等的哈希码(或者散列码)。
2、如果两个对象的hashCode相同,它们并不一定相同。
不同对象中重写的equal()里,一般比较的全面、复杂,这样效率就比较低;而利用hashCode()进行对比,则只要生成一个hash值进行比较就可以了,效率很高,但两个不同对象的hashCode可能相同,所以hashCode的比较不是绝对可靠的。
为保证对比大量数据的效率和绝对正确性,对比时,首先用hashCode()去对比,如果hashCode()不一样,返回这两个对象不相等的结果(也就是不必再用equal()去再对比了);如果hashCode()相同,此时再对比他们的equal(),如果equal()也相同,则返回这两个对象相同的结果。
参考:https://www.cnblogs.com/keyi/p/7119825.html
为什么重写equals就要重写hashCode
如果重写了equals,比如说是基于对象的内容实现的,而hashCode未重写,那么很可能某两个对象明明是“相等”,而hashCode却不一样。
问题出现:当把两个对象作为hashMap、hasoTable或hashSet的key时,map中就会存在两个“相等”的key
重写hashcode注意事项:
1. 如果hashcode方法用到了对象类型,那么该对象类型也必须要重写hashcode方法
2. 为了避免相同的对象计算出不同的hash值,hashcode中应计算所有出现在equals中的字段,且不能加入其他字段
3. 在JVM中,n*31会被优化(n<<5)-n,移位和减法的操作效率比乘法的操作效率高很多
4. 谷歌的架构师指出,需初始化一个整形变量,为此变量赋予一个非零的常数值,比如int hash= 17;
eg:
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age && gender == person.gender && Objects.equals(name,person.name);
}
@Override
public int hashCode() {
int hash = 17;
hash = hash * 31 + getName()!=null?getName().hashCode():0;
hash = hash * 31 + getAge()!=null?getAge():0;
hash = hash * 31 + getGender()!=null?getGender().hashCode():0;
return hash;
}
5. 对于类的hashCode、get、set等方法,可以使用依赖lombok的注解来完成
本文深入解析Java中==和equals的区别,探讨它们在值类型和引用类型中的应用,以及equals与hashCode的关系,通过实例说明如何正确重写equals和hashCode方法。


被折叠的 条评论
为什么被折叠?



