• 判断Set里的元素是否重复、==、equals、hashCode方法研究-代码演示


    被测试类,没有重写hasCode()和equals()方法:

    package niukewang;
    
    import java.util.Objects;
    
    public class setClass {
    
        String a;
        String b;
        public setClass(String a, String b)
        {
            this.a=a;
            this.b=b;    
        }
    }


    测试类:

    package niukewang;
    
    import java.util.HashSet;
    import java.util.Set;
    
    public class test1 {
    
        public static void main(String args[]) 
        { 
            setClass s1=new setClass("http://www.yjbys.com/", "");
            setClass s2=new setClass("http://www.yjbys.com/", "");
            setClass s3=new setClass("http://www.yjbys.com/", "");
            
            Set<setClass> set=new HashSet<>();
            set.add(s1);
            set.add(s2);
            set.add(s3);
            
            String ss=new String("Hello");
            String ss1=new String("Hello");
            System.out.println(ss==ss1);
            System.out.println(ss.equals(ss1));
            System.out.println(ss.hashCode()==ss1.hashCode());
            
            System.out.println("set....");
            
            System.out.println(s1==s2);
            System.out.println(s1.equals(s2));
            System.out.println(s1.hashCode()==s2.hashCode());
            System.out.println("Number is "+set.size());
        }
    }

    输出结果:
    false   (string不是同一个对象)
    true    (只要值相同就行了)
    true    (hashcode也相同)
    set....
    false    (不是同一个对象)
    false    
    false
    Number is 2

    这是没有覆盖hashCode()和equals()方法的情况。

    被测试类覆盖hashCode()和equals()方法:

    package niukewang;
    
    import java.util.Objects;
    
    public class setClass {
    
        String a;
        String b;
        public setClass(String a, String b)
        {
            this.a=a;
            this.b=b;    
        }
        
        public int hashCode() {
            return a.hashCode();
        }
        
        public boolean equals(Object obj)
        {
            if(obj==null) return false;
            
            if(getClass() != obj.getClass()) return false;
            
            final setClass s=(setClass)obj;
            
            return Objects.equals(this.a, s.a);
        }
    }

    覆盖之后,hascode的值就是设置的a的hashcode,equals()比较的也是a的hashcode的值。
    测试结果输出:

    false
    true
    true
    set....
    false
    true
    true
    Number is 1

    set内部实现实际是map,在处理map的key的时候调用了hashcode方法,HashMap中有代码如下

     static final int hash(Object key) {
            int h;
            return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
        }

    调试证明:把元素往set中添加时,首先会对比hashcode是否相等,如果hashcode不相等就直接往set中加这个元素,如果 hashcode相等就对比equals方法,如果equals不相等就往set中加这个元素,所以set的元素重复性是根据hashcode和 equals方法来判断的,

        对于为什么覆盖equals方法就一定要覆盖hashcode方法的原因也显示了出来:由于是先调用hashcode方法的,如果不覆盖hashcode 方法,默认会去取内存的物理地址作为生成hashcode的依据,那么两个不同的对象的hashcode必然不同的,于是直接结束添加了,根本没法调用到 equals方法,就不用说equals内部实现如何了,不管equals是返回true还是false都没机会调用到了。

        由于set内部是用map实现的,所以往map中put元素的时候是一样的原理。

    证明如果不重写hashcode方法,无论equals是返回true还是返回false都没有用,因为在调用equals方法之前会先调用hashcode方法,在调用hashcode方法的时候

    就已经被认为这些对象全部是不重复的元素,直接往set中添加这些对象,并完成添加,equals方法就没有机会调用到。

    借鉴博文:http://www.cnblogs.com/langtianya/p/4421582.html

  • 相关阅读:
    生成二维码
    【C#】教你纯手工用C#实现SSH协议作为GIT服务端
    Git断点续传和离线增量更新的实现
    微信定位真的泄露了你的精确位置
    Helper Files
    正则表达式的一些应用
    Apache配置SSL实现HTTP转HTTPS及可能出现的问题(配置https启动不了的解决办法)
    Python3 采集APP数据及相关配置
    Laravel 5 中间件、路由群组、子域名路由、 权限控制的基本使用方法
    Python3使用cookielib模块
  • 原文地址:https://www.cnblogs.com/Berryxiong/p/6135707.html
Copyright © 2020-2023  润新知