什么情况下需要重写equals方法,为什么一定需要重写hashcode

目录

  • 一.什么情况下需要重写equals方法?
      • 1.正常情况下,Java的基本数据类型和包装数据类型都已经重写的Object类的equals方法和hashCode方法
      • 2.已经实现了我们想要的目的:只考虑name属性是否相同,不考虑age属性的异同来判断Coder对象是否相等.
  • 二.为什么一定需要重写hashcode方法?
      • 1.我们把重写的hashcode方法注释掉之后,对两个new Coder("lxyer",22)对象就行获取hashCode,得到的两个hash值完全不同,因为没有重写hashCode方法,会使用Object的hashCode方法,是依据对象的内存地址进行hash算法取得的值.
      • 2.不重写hashCode方法,如果我们进行equals判断两个对象是否相等的时候,明明两个对象所有的属性都相同,但是内存地址不同,进而两个对象的hashCode也不同,在使用HashMap,HashSet等需要依赖hash值的数据结构时,就会出现相同的对象因hash值不同,储存到了不同的哈希槽中,产生了错误的结果.

一.什么情况下需要重写equals方法?

1.正常情况下,Java的基本数据类型和包装数据类型都已经重写的Object类的equals方法和hashCode方法

需要重写equals方法的场景:主要依据我们的业务场景来看,例如:当我们对Coder这个对象进行判断的时候,我们不需要Coder的所有的属性都必须相同,则可以重写Coder的equals方法,和hashCode()方法,达到只判断Coder的name相同即为对象相同,而不需要考虑其他的age等属性是否相同.

public void hashCodeTest() {
        Coder coder = new Coder("lxyer", 22);
        Coder coder1 = new Coder("lxyer1", 221);
        Coder coder2 = new Coder();
        coder2.setAge(222);
        coder2.setName("lxyer");
        System.out.println(coder.hashCode());
        System.out.println(coder1.hashCode());
        System.out.println(coder2.hashCode());
        System.out.println(coder.equals(coder2));
        Set set = new HashSet();
        set.add(coder);
        set.add(coder1);
        set.add(coder2);
        System.out.println(set.size());
    }

    @Data
    public class Coder {
        private String name;
        private int age;

        public Coder() {
        }

        public Coder(String name, int age) {
            this.name = name;
            this.age = age;
        }

        @Override
        public boolean equals(Object o) {
            if (o==null) {
                return false;
            }
            if (o==this) {
                return true;
            }
            if (o.getClass()!=this.getClass()) {
                return false;
            }
            Coder other = (Coder) o;
            if (other.getName()==this.getName()) {
                return true;
            }
            return false;
        }

        @Override
        public int hashCode() {
            //hash使用素数
            int hash = 17;
            return hash*31+getName().hashCode();
        }
    }
//输出结果为:
103435241
103435241
103435241
true
1

2.已经实现了我们想要的目的:只考虑name属性是否相同,不考虑age属性的异同来判断Coder对象是否相等.

二.为什么一定需要重写hashcode方法?

1.我们把重写的hashcode方法注释掉之后,对两个new Coder(“lxyer”,22)对象就行获取hashCode,得到的两个hash值完全不同,因为没有重写hashCode方法,会使用Object的hashCode方法,是依据对象的内存地址进行hash算法取得的值.

2.不重写hashCode方法,如果我们进行equals判断两个对象是否相等的时候,明明两个对象所有的属性都相同,但是内存地址不同,进而两个对象的hashCode也不同,在使用HashMap,HashSet等需要依赖hash值的数据结构时,就会出现相同的对象因hash值不同,储存到了不同的哈希槽中,产生了错误的结果.

//把重写的hashcode方法注释掉之后的结果
1681215776
1689723487
870019773
true
3

你可能感兴趣的:(源码,Java)