java中equals和==【各种包括面试题】
1.对于java中==
java中的数据类型,可分为两类:
1.基本数据类型,也称原始数据类型。
byte,short,char,int,long,float,double,boolean 他们之间的比较,应用双等号(==),比较的是他们的值。
基本数据类型比较(string 除外), == 是比较值;
2.复合(引用)数据类型(类)
当他们用()进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。(stu==stu)
2.java类中equals
JAVA当中所有的类都是继承于Object这个基类的,在Object中的基类中定义了一个equals的方法,
public boolean equals(Object obj) {
return (this == obj);
}
这个方法的初始行为是比较对象的内存地址, 对于复合数据类型之间进行equals比较,在没有覆写equals方法的情况下,他们之间的比较还是基于他们在内存中的存放位置的地址值的,但在一些类库当中这个方法被覆盖掉了,如java.io.file,java.util.Date,java.lang.string,包装类(Integer,Double等)在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了。
比如:
String中Equals()方法:字符串内容的比较。最好把常量放在前面。
因为Object的equals方法也是用双等号(==)进行比较的,所以没有覆写equals方法的,比较后的结果跟双等号(==)的结果相同。
总结:
1.对于==,
如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;null被视为基本数据类型【这也是为什么对象为null时.方法()会报错的原因】
如果作用于引用类型的变量,则比较的是所指向的对象的地址是否相等
(new 出来的
String strA=new String(“s”),
String strB=new String(“s”),
即使其内容一样,地址不会一样,所以strA==strB,会false)
(直接赋值时,包括String,包装类类型等)
字符串常量池:
String s1="abc";
String s2="abc";
System.out.println(s1==s2); (直接赋值时,所引用的地址相同)
结果:true;
直接赋值:只会产生一个实例化对象,并且可以自动保存到对象池中(A=“mldn”=B),以实现该字符串实例的重用。
构造方法:会产生两个实例化对象,并且不会自动入池,无法实现对象重用,可以利用intern()方法手工入池。
String str=new String("1234").intern();
String str2="1234";
System.out.println(str==str2);
结果:true;
包装类(除Float和Double类型,整数型(-128--127),Character(单字符(不包括汉字)),都有缓冲池,只要在此范围内只会有一个对象,可以使用==比较(true),超过此范围则为false,最好使用equals()比较,Boolean(直接赋值时只有true和false))
Integer s1=23;
Integer s2=23;
System.out.println(s1==s2);//true
Integer s3=128;
Integer s4=128;
System.out.println(s3==s4);//false
阿里巴巴开发手册(有需要的同学可以到如下地址下载https://download.youkuaiyun.com/download/hnpifkso/11249974)
2.对于(Object类中的)equals方法,注意:equals方法不能作用于基本数据类型的变量
如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;
诸如String、Date,包装类等类对equals方法进行了重写的话,比较的是所指向的对象的内容
String类也对Object类的hashCode()(hashCode()方法,此方法默认返回是对象的物理地址所转换而来的十进制的hash值)进行了覆写,返回字符串内容的地址hash值
3,对象比较equals处理
在进行2个对象比较时,需要覆写equals和hashcode,否则默认比较是地址
Contains(),remove()等方法查询时,删除等时需要覆写equals()和hashCode(),包括集合中equals和hashCode解决了重复元素的判断处理(例如HashSet,hashmap)
步骤:
①、如果子类能够拥有自己的相等概念,则对称性需求将强制采用 getClass 进行检测。【理解:确保是同一个类的对象】
②、如果有超类决定相等的概念,那么就可以使用 instanceof 进行检测,这样可以在不同的子类的对象之间进行相等的比较。【理解:
总有些人喜欢那子类和父类比较】
下面给出一个完美的 equals 方法的建议:
1、显示参数命名为 otherObject,稍后会将它转换成另一个叫做 other 的变量。
2、判断比较的两个对象引用是否相等,如果引用相等那么表示是同一个对象,那么当然相等
3、如果 otherObject 为 null,直接返回false,表示不相等
4、比较 this 和 otherObject 是否是同一个类:如果 equals 的语义在每个子类中有所改变,就使用 getClass 检测;如果所有的子类都有统一的定义,那么使用 instanceof 检测
5、将 otherObject 转换成对应的类类型变量
6、最后对对象的属性进行比较。使用 == 比较基本类型,使用 equals 比较对象。如果都相等则返回true,否则返回false。注意如果是在子类中定义equals,则要包含 super.equals(other)
下面我们给出 Person 类中完整的 equals 方法的书写:
@Override
public boolean equals(Object otherObject) {
//1、判断比较的两个对象引用是否相等,如果引用相等那么表示是同一个对象,那么当然相等
if(this == otherObject){
return true;
}
//2、如果 otherObject 为 null,直接返回false,表示不相等
if(otherObject == null ){//对象为空或者不是Person类的实例
return false;
}
//3、比较 this 和 otherObject 是否是同一个类(注意下面两个只能使用一种)
//3.1:如果 equals 的语义在每个子类中所有改变,就使用 getClass 检测
if(this.getClass() != otherObject.getClass()){
return false;
}
//3.2:如果所有的子类都有统一的定义,那么使用 instanceof 检测
if(!(otherObject instanceof Person)){
return false;
}
//4、将 otherObject 转换成对应的类类型变量
Person other = (Person) otherObject;
//5、最后对对象的属性进行比较。使用 == 比较基本类型,使用 equals 比较对象。如果都相等则返回true,否则返回false
// 使用 Objects 工具类的 equals 方法防止比较的两个对象有一个为 null而报错,因为 null.equals() 是会抛异常的
return Objects.equals(this.pname,other.pname) && this.page == other.page;
//6、注意如果是在子类中定义equals,则要包含 super.equals(other)
//return super.equals(other) && Objects.equals(this.pname,other.pname) && this.page == other.page;
}
insatnceof:
instanceof 严格来说是Java中的一个双目运算符,用来测试一个对象是否为一个类的实例,用法为:
1 |
|
其中 obj 为一个对象,Class 表示一个类或者一个接口,当 obj 为 Class 的对象,或者是其直接或间接子类,或者是其接口的实现类,结果result 都返回 true,否则返回false。
注意:编译器会检查 obj 是否能转换成右边的class类型,如果不能转换则直接报错,如果不能确定类型,则通过编译,具体看运行时定。
更详细:
https://www.cnblogs.com/ysocean/p/8419559.html
https://blog.youkuaiyun.com/qq_19934363/article/details/89930129
Equals 和 hashCode的关系
hashCode():此方法返回是对象的物理地址所转换而来的十进制的hash 值(代地址)
Equals()和hashcode()必须遵守以下规则:
(1)如果两个对象执行equals()方法是相等的,那么执行hashcode()方法的结果也必须是相等的;
(2)如果两个对象执行equals()方法不相等,那么执行hashcode()方法的结果可以相等也可以不相等。
第一种:
@Override
public int hashCode() {
// TODO 自动生成的方法存根
return Objects.hash(this.name,this.color);//可以传多种多个参数
}
第二种:
//系统自动生成的
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((color == null) ? 0 : color.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
4.Js,JQuery里面没有equals
可以使用==比较,它会把字符串拆成字符数组,一个一个字符进行比较。相当于java里面String类里面的equals()
5,面试题
1)对于==,比较的是值是否相等
如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;
如果作用于引用类型的变量,则比较的是所指向的对象的地址
2)对于equals方法,注意:equals方法不能作用于基本数据类型的变量,equals继承Object类,比较的是是否是同一个对象
如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;
诸如String、Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容。(上边有全的)