弄懂==、equals、hashCode

作者: 王小贱_ww | 来源:发表于2018-01-18 11:30 被阅读235次

      这篇文章讲一下这3个的知识点,需要对java执行过程中内存过程有点了解,可以看看上一篇文章程序执行过程的内存分析
    UserBean类

    public class UserBean {
    
        private String name;
        private int age;
        private String sex;
        private int height;
    
    
        public UserBean(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public String getSex() {
            return sex;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    
        public int getHeight() {
            return height;
        }
    
        public void setHeight(int height) {
            this.height = height;
        }
    
    
    }
    
    UserBean user1=new UserBean();
    UserBean user2=new UserBean();
    System.out.println(user1==user2);
    System.out.println(user1.equals(user2));
    

    运行结果:false false
    我们先看一下equals的源码:

     public boolean equals(Object obj) {
            return (this == obj);
        }
    

    而==看的是user1和user2的地址,很显然,二者地址不一样,所有都是false。
      如果我们想有自己的比较方式,不想比较地址值,想比较name是否相同,从而判断两个user是否一样,我们应该重写equals方法

      @Override
        public boolean equals(Object obj) {
            UserBean bean = (UserBean) obj;
            return this.name == bean.name;
        }
    

    这样运行的结果是:false true

    hashCode

      在讲hashCode之前,先看一段代码:

    HashSet hashSet = new HashSet();
    hashSet.add(new UserBean("a1", 22));
    hashSet.add(new UserBean("a2", 23));
    hashSet.add(new UserBean("a3", 24));
    hashSet.add(new UserBean("a1", 22));
    
    Iterator iterator = hashSet.iterator();
    while (iterator.hasNext()) {
                UserBean userBean = (UserBean) iterator.next();
                System.out.println("name:" + userBean.getName() + "   age:" + userBean.getAge());
            }   
    

    打印的结果:
    name:a2 age:23
    name:a1 age:22
    name:a1 age:22
    name:a3 age:24
    (图片下面再解释)


    1.png

      可以看出1.HashSet没有顺序 2.name为a1 age为22的两个数据应该是重复了,但是还是被添加了进来。。。。。。。我们难道应该重写equals?来判断两个对象是否一样,如果一样,就不添加。

     @Override
        public boolean equals(Object obj) {
            UserBean userBean = (UserBean) obj;
            System.out.println(this.name + "....equals..." + userBean.name);
            return this.name == userBean.name && this.age == userBean.age;
        }
    

      重写方法后,运行依旧没有 System.out.println(this.name + "....equals..." + userBean.name);打印这个,说明没有走equals方法,这个时候就需要hashcode登场了。

     public int hashCode() {
     System.out.println("...hascode...");
             return  60;
        }
        
        public boolean equals(Object obj) {
            UserBean userBean = (UserBean) obj;
            System.out.println(this.name + "....equals..." + userBean.name);
            return this.name == userBean.name && this.age == userBean.age;
        }
    

    打印结果:

    ...hascode...
    ...hascode...
    a2....equals...a1
    ...hascode...
    a3....equals...a1
    a3....equals...a2
    ...hascode...
    a1....equals...a1
    name:a1 age:22
    name:a2 age:23
    name:a3 age:24


    2.png

      在hash表中,1先进来(给个hashcode),2再次进来,hashcode和1的值一样,在判断name和age(二者不一样),得出1和2是两个值,所以把2添加进来,这是因为2和1的hashcode值一样,所以把2挂到1上去。以此类推,最后一个值重复了,所以不添加。
      从效率上来考虑,每次进来都要hashcode 和equals,有点复杂,我们可以根据业务需求,自己建立值,能提高效率

      public int hashCode() {
            System.out.println("...hascode...");
             return  name.hashCode()+age*36;
        }
        
        public boolean equals(Object obj) {
            UserBean userBean = (UserBean) obj;
            System.out.println(this.name + "....equals..." + userBean.name);
            return this.name == userBean.name && this.age == userBean.age;
        }
    

    打印结果:(只比较了一次)
    ...hascode...
    ...hascode...
    ...hascode...
    ...hascode...
    a1....equals...a1
    name:a3 age:24
    name:a1 age:22
    name:a2 age:23


    3.png
    总结:HashSet怎么能确保数据的唯一性??

      通过hascode和equals,如果hascode元素相同,才会判断equals是否为true,如果hashcode不同,不会调用equals。

    相关文章

      网友评论

        本文标题:弄懂==、equals、hashCode

        本文链接:https://www.haomeiwen.com/subject/xciioxtx.html