如何正确的重写equals() 和 hashCode()方法

本文介绍了在Java中如何正确地重写equals和hashCode方法。通过三种常见方法:经典方式、JDK7新特性及Apache Commons Lang库,确保对象比较的一致性和哈希表中的正确行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在比较两个Java对象时, 有时候我们需要重写equalshashCode方法。

public class User{    
   private String name;
   private int age;
   private String passport;

//getters and setters, constructor
}

在比较结果时:

User user1 = new User("mkyong", 35, "111222333");
User user2 = new User("mkyong", 35, "111222333");

System.out.println(user1.equals(user2)); // false

下面我们将介绍几种常用方法:

1. 经典方式
这种17和31散列码的想法来自经典的Java书籍——《Effective Java》第九条。下面我们来看看是如何实现的…

public class User {
    private String name;
    private int age;
    private String passport;
    //getters and setters, constructor
    @Override
    public boolean equals(Object o) {
        if (o == this) return true;
        if (!(o instanceof User)) {
            return false;
        }
        User user = (User) o;
        return user.name.equals(name) &&
                user.age == age &&
                user.passport.equals(passport);
    }
    //Idea from effective Java : Item 9
    @Override
    public int hashCode() {
        int result = 17;
        result = 31 * result + name.hashCode();
        result = 31 * result + age;
        result = 31 * result + passport.hashCode();
        return result;
    }
}

2. JDK7
对于JDK7及更新版本,你可以是使用java.util.Objects 来重写 equals 和 hashCode 方法,代码如下:

import java.util.Objects;

public class User {
    private String name;
    private int age;
    private String passport;

    //getters and setters, constructor

    @Override
    public boolean equals(Object o) {
        if (o == this) return true;
        if (!(o instanceof User)) {
            return false;
        }
        User user = (User) o;
        return age == user.age &&
                Objects.equals(name, user.name) &&
                Objects.equals(passport, user.passport);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age, passport);
    }

}

3 . Apache Commons Lang
或者你可以使用Apache Commons LangEqualsBuilderHashCodeBuilder 方法。代码如下:

import org.apache.commons.lang3.builder;

public class User {
    private String name;
    private int age;
    private String passport;
    //getters and setters, constructor

     @Override
    public boolean equals(Object o) {

        if (o == this) return true;
        if (!(o instanceof User)) {
            return false;
        }
        User user = (User) o;

        return new EqualsBuilder()
                .append(age, user.age)
                .append(name, user.name)
                .append(passport, user.passport)
                .isEquals();
    }
    @Override
    public int hashCode() {
        return new HashCodeBuilder(17, 37)
                .append(name)
                .append(age)
                .append(passport)
                .toHashCode();
    }
}

最后测试总结:
在使用上述三种任何一种方式都可以到如下结果:

User user1 = new User("mkyong", 35, "111222333");
User user2 = new User("mkyong", 35, "111222333");
System.out.println(user1.equals(user2)); // true

其实后两种都是对于17和31散列码思想的封装实现。具体请参考《Effective Java》第九条。



版权(c)声明:
本篇文章系转载,版权归原作者所有,在此并无任何商业用途或其他盈利性用途,转载请务必注明出处!
原文地址:https://blog.youkuaiyun.com/zzg1229059735/article/details/51498310
译文地址:http://www.mkyong.com/java/java-how-to-overrides-equals-and-hashcode/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值