equals与==的区别

equals与==的区别

1、一个对象的hashCode取是对象在JVM保存的值,不同的引用对象分配堆的位置不一样,hashCode一定不同。

2、== 比较引用对象,比较的是两个对象hashcode 值, == 比较两个常量总是指向常量池中同一个对象,所以总是相同的。

3、 在不重写hashcode 和equals情况下,Object对象equal底层也是== 实现,比较两个对象的内存地址,== 和equals没有什么区别。

4、 在重写equal 和hashcode时一般遵循一个原则:

  重写equals也重写hashcode,并且保证equals相等的对象,hashCode也相等。

从业务角度考虑:如果你只重写了equals,没有重写hashCode,可能导致equals相同,hashCode不相等。在应用层面使用equals写业务逻辑判断对象是否相同,插入到集合中,集合中使用hashCode作为判断是否相同的对象,同一个集合中存储了对各对象,这和你编写代码的初衷不一致。

为什么HashMap两个不同的对象的可能映射到同一个位置?

因为并没有并没有直接使用key对象的内存地址作为映射地址,而是对key的内存地址进行一个hash函数映射。HashSet存储时先判断key得到hashcode()是否相同,hashcode值相同(此时只能说映射到了同一个位置,产生了哈希冲突,不能说key值本身内存地址有重复),还需要使用equals()函数对key进行判断,equals也相同,则认为元素已经存在,默认equals中使用对象地址判断两个对象是存在,内存地址不相同的两个对象一定不相等

为什么不直接使用对象内存地址哈希映射值?

HashMap和HashSet的key值直接,内存地址很大,不映射直接作为hash值,存储元素非常少时,会造成极大的空间浪费。

应用举例:创建一个学生类,在各种集合中,只要名字相同就认为是同一个学生。

hashCode的重写实现需要满足不变性,即一个object的hashCode不能前一会是1,过一会就变成2了。hashCode的重写实现最好依赖于对象中的final属性,从而在对象初始化构造后就不再变化。

public class Student {
    private String name;
    private Integer  age;
    public Student(){}

    public Student(String name) {
        this.name = name;
    }

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public boolean equals(Object obj) {
        return ((Student)obj).getName().equals(this.name);
    }

    @Override
    public int hashCode() {
        return this.name.hashCode();
    }
}

测试类
public class Main1 {


    public static void main(String[] args) {
      Student stu1= new Student("张三",12);
      Student stu2 = new Student("张三",14);
      System.out.println(stu1 == stu2);//重写hashCode和equals前后,都是false
      System.out.println(stu1.equals(stu2));//重写equals前时false,重写后时true


      HashMap<Student,Integer>  map = new HashMap<>();
      map.put(stu1,1);
      map.put(stu2,2);
      System.out.println(map.size());//重写hashCode和equals之前size=2,同时重写equal和false后为size =1,只重写equals,size=2
    }



}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值