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


 

        SiteBean site1 = new SiteBean("http://www.yjbys.com/", "");
        SiteBean site2 = new SiteBean("http://www.yjbys.com/", "");
        Set<SiteBean> aaSet = new HashSet<>();
        aaSet.add(site1);
        aaSet.add(site2);
System.out.println(site1
== site2); System.out.println(site1.equals(site2)); System.out.println(site1.hashCode() == site2.hashCode()); SiteBean site3 = new SiteBean("http://www.yjby1s.com/11", ""); SiteBean site4 = new SiteBean("http://www.yjby1s.com/11", ""); aaSet.add(site3); aaSet.add(site4);
SiteBean 重写了hashCode和equals方法,代码如下:

 //比较的是域名
    @Override
    public int hashCode() {
        return siteUrl.hashCode();
    }

    //比较的是域名
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }

        if (getClass() != obj.getClass()) {
            return false;
        }
        final SiteBean siteBean = (SiteBean) obj;
        return Objects.equals(siteUrl, siteBean.siteUrl);
    }

输出如下:

false
true
true
且set中元素的个数是2.

 

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

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

 

下面尝试不重写hashcode方法,即默认使用Object的hashcode方法(代码省略):

输出:

false
true
false
且set中元素的个数是4

    调试证明:把元素往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方法(代码省略):

输出:

false
false
false
且set中元素的个数是4

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

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

作者:欧初权

转载注明:http://www.cnblogs.com/langtianya/p/4421582.html

好的,我来为您演示一下如何实现这个类: ```java public class Apple { private double weight; public Apple(double weight) { this.weight = weight; } public double getWeight() { return weight; } public void setWeight(double weight) { this.weight = weight; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false; Apple apple = (Apple) obj; return Double.compare(apple.weight, weight) == 0; } @Override public int hashCode() { return Objects.hash(weight); } @Override public String toString() { return "Apple{" + "weight=" + weight + '}'; } } ``` 在这个类中,我们定义了一个私有属性 `weight` 表示苹果的重量,以及一个构造方法 `Apple(double weight)` 用于初始化这个属性。同时,我们还提供了相应的 setter 和 getter 方法。 为了让两个苹果的重量相等时被判断为相等,我们需要重写 `equals` 方法。在这个方法中,我们首先判断两个对象是否为同一个对象,如果是则直接返回 `true`。接着,我们判断传入的对象是否为 `Apple` 类型,如果不是则返回 `false`。最后,我们比较两个苹果的重量是否相等,如果相等则返回 `true`,否则返回 `false`。 为了保证重载的 `equals` 方法可以正常工作,我们还需要重写 `hashCode` 方法。在这个方法中,我们使用 `Objects.hash` 方法根据苹果的重量计算出一个哈希值。 最后,我们还重写了 `toString` 方法,用于打印出苹果的重量。 现在,我们可以根据这个类来创建 5 个不同重量的苹果: ```java Apple a1 = new Apple(0.5); Apple a2 = new Apple(0.5); Apple a3 = new Apple(0.8); Apple a4 = new Apple(0.3); Apple a5 = new Apple(1.0); ``` 如果我们想判断两个苹果是否相同,只需要使用 `equals` 方法即可: ```java System.out.println(a1.equals(a2)); // true System.out.println(a1.equals(a3)); // false ``` 如果我们想打印出一个苹果的信息,可以使用 `toString` 方法: ```java System.out.println(a1.toString()); // Apple{weight=0.5} ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值