一.“ == ”
1.“==”对于基础数据类型进行值的比较,引用数据类型而言是内存地址的比较
2.由于引用数据类型可以new,可以直接赋值
A.new的存在于堆中,直接赋值的存在于常量池中
B.常量池中值相同则内存地址相同,因为都会转化成byte数组。堆中不可能出现内存地址相同
https://www.cnblogs.com/guodongdidi/p/6953217.html
二.equals
equals是比较内存,不过可以重写让其比较值,那么怎样重写equals方法?
@Override
public boolean equals(Object obj)
{
if(this==obj)//对于引用类型,“==”是地址的比较。地址值相同就是一个对象
return true;
//向下转型,这样就可以利用student特有的变量
if(obj instanceof student)
{
student s1=(student)obj;
//Object.equals可以防止空指针异常
return this.age==s1.age && Objects.equals(this.name, s1.name);
}
return false;
}
objects.equals中的源码,防止空指针异常
//这是一个静态方法,不能重写,直接调用
//'||'有短路操作,如果二者内存地址想等就直接短路掉了
public static boolean equals(Object a,Object b)
{
return (a==b)||(a!=null && a.equals(b));
}
三.为什么重写equals方法一定要重写hashcode?
object 类对equals和hashcode的定义有如下要求:二者equals那么hashcode必然想等
public class test
{
public static class student{
private int age;
private String name;
@Override
public boolean equals(Object obj)
{
if(this==obj)
return true;
if(obj instanceof student)
{
student s1=(student)obj;
return this.age==s1.age && Objects.equals(this.name, s1.name);
}
return false;
}
}
public static void main(String args[])
{
student s1=new student();
student s2=new student();
System.out.println(s1.equals(s2));//true
System.out.println(s1.hashCode());//1259475182
System.out.println(s2.hashCode());//1300109446
HashMap<student, String> map=new HashMap<student, String>();
map.put(s1,"123");
map.put(s2,"456");
System.out.println(map.get(s1));//123
System.out.println(map.get(s2));//456
}
}
通过上面的代码可以看出:虽然s1和s2equals,但是hashcode并不想等,与Object中对hashcode的要求不符合 ?所以会造成在使用hashMap时是两个key
hashcode 仅与内存地址相关,所以两个new出来的对象哈希值大概率不同
下面重写hashcode()
public class test
{
public static class student{
private int age;
private String name;
@Override
public boolean equals(Object obj)
{
if(this==obj)
return true;
if(obj instanceof student)
{
student s1=(student)obj;
return this.age==s1.age && Objects.equals(this.name, s1.name);
}
return false;
}
@Override
public int hashCode()
{
return Objects.hash(age,name);
}
}
public static void main(String args[])
{
student s1=new student();
student s2=new student();
System.out.println(s1.equals(s2));//true
System.out.println(s1.hashCode());//1259
System.out.println(s2.hashCode());//1259
HashMap<student, String> map=new HashMap<student, String>();
map.put(s1,"123");
map.put(s2,"456");
System.out.println(map.get(s1));//456
System.out.println(map.get(s2));//456
}
}
发现重写了hashCode()后,就不会出现上述问题