equals和hashCode方法

hashCode

hashCode :哈希码或者散列码。应该是表示对象特征值的**int整数。**如果没有任何类去覆盖hashCode方法,哈希码的值就是对象在内存中的地址。但是缺省的哈希码的值是没有什么太大意义的。实际中需要我们去覆盖hashCode 方法。

equals

equals方法用来判断两个对象从逻辑上是否相等,并不是判断两个对象是否是同一个对象。

hashCode 和 equals怎么写

这两个方法是我们经常去要覆盖的方法。
覆盖原则:equals为true,hashCode就应该相等。这是一种约定俗称的规范。即:equals为true是hashCode相等的充分非必要条件。hashCode 相等是equals为ture的必要不充分条件。
IDEA可以帮助我们重写equals和hashCode方法。下边就是通过IDEA自动生成的equals和hashCode方法

    @Override
    public boolean equals(Object o) {
        if (this == o) return true; // 先判断两个对象是不是同一个对象,通过引用是否相等进行判断。
        if (!(o instanceof MerchandiseV2)) return false;// 判断 是不是我本省或者我的子类如果不是,那么直接返回false即可。
        MerchandiseV2 that = (MerchandiseV2) o; // 业务逻辑上判断是否相等。
        return getCount() == that.getCount() &&
                Double.compare(that.getSoldPrice(), getSoldPrice()) == 0 &&
                Double.compare(that.getPurchasePrice(), getPurchasePrice()) == 0 &&
                getName().equals(that.getName()) &&
                getId().equals(that.getId());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getName(), getId(), getCount(), getSoldPrice(), getPurchasePrice());
    }

String的equals方法

Java 字符串有优化,有专门的地方用来存储字符串,如果你创建的字符串不是很长,并且整个程序运行时创建字符穿的地方没有那么多的话,他会把字符串放在同一个地方,如果你再创建字符串,java在创建之前会去找字符串是不是已将创建了,如果有,会直接返回那个引用,为什么可以这样,因为Sting类是不可变的,不能写不能改。所以java可以放心大胆的取出整个引用,而不去再创建新的。当然如果创建的字符串很长超过了Java的优化限制,也会创建一个新的字符串。因此String 还是用equals去比较是否相等,最为稳妥,从而不会因为JAVA的优化机制而产生误判。

总结

1、Object中的hashCode和equasl方法,我们应该用IDE帮我们生成的hashCode和equasl方法去判断两个对象是否相等。
2、String中的一些优化,让我们认为应该是不等的两个对象却是相等的。因此比较对象是否相等,就用equals即可。

已标记关键词 清除标记
<br />使用乐观锁,在数据库中使用了一个 version 列,对应 Hibernate POJO有一个 version 属性。 <br />在实现 HashCode, equals 方法时是不是不能包括 version 属性呢? <br /> <br />对于如下 POJO 类 <br />public class User { <br />   private Integer id; <br />   private String name; <br />   private String fist_name; <br />   private String last_name; <br />   private String password; <br />   private String password_hint; <br />   private String email; <br />   private String address; <br />   private String city; <br />   private String post_code; <br />.... <br />   private Integer version; <br />... <br /> <br />} <br />主键是 Id, 关键属性是 name, email ,其它可以为 null。 <br /> <br />在 HashCode,equals  中是包含 id,name,email ,还是包含除了 version 之外的所有列?<br /><strong>问题补充:</strong><br />如果这样的类,该如何确定业务键属性: <br />public class Road{ <br />   private Integer Id; <br />   private Set<location> locations = new HashSet<location>(); <br />   private Type type; <br /> <br />  get/set <br />... <br />}<br /><strong>问题补充:</strong><br />Road 类的含议是: <br />每条道路含有N个地点:locations <br />每条道路有一种类型,比如国家一级路,省级路等:type <br /> <br />在这种情况下,用locations,type可以确定一条线路。但是《深入浅出 Hibernate》上讲不能使用集合作为业务关键字,否则会引起很多问题。 <br /> <br />而 Hibernate 又不能以 id 为业务关键字。那么就只能以Type为关键字,这样的话,根本不能生成有效的 HashCode()和equals() <br /> <br />怎么办? <br /><br /><strong>问题补充:</strong><br />to mccxj : <br />很有道理,谢谢。 <br /> <br />现在,我想将 roadLocation 加入 Set 集合 <br /> <br />public class RoadLocation  implements java.io.Serializable { <br /> private Integer id; <br /> private Road road; //道路对象 <br /> private Location location; //地点对象 <br /> private Integer mileage; //里程 <br />.. <br />在 HashCode, equals中是否可以 <br /> @Override <br /> public boolean equals(Object obj) { <br /> if (this == obj) <br /> return true; <br /> if (getClass() != obj.getClass()) <br /> return false; <br /> RoadLocation other = (RoadLocation) obj; <br /> if (location == null) { <br /> if (other.location != null) <br /> return false; <br /> } else if (!location.equals(other.location)) <br /> return false; <br /> if (mileage == null) { <br /> if (other.mileage != null) <br /> return false; <br /> } else if (!mileage.equals(other.mileage)) <br /> return false; <br /> if (road == null) { <br /> if (other.road != null) <br /> return false; <br /> } else if (!road.equals(other.road)) <br /> return false; <br /> return true; <br /> } <br /> <br /> @Override <br /> public int hashCode() { <br /> final int prime = 31; <br /> int result = prime <br /> + ((location == null) ? 0 : location.hashCode()); <br /> result = prime * result + ((mileage == null) ? 0 : mileage.hashCode()); <br /> result = prime * result + ((road == null) ? 0 : road.hashCode()); <br /> return result; <br /> } <br /> <br />这里是使用 road,location 比较,还是使用 road.getName location.getName 比较好呢? <br /><br /><strong>问题补充:</strong><br />不知我是不是太笨了,竟找不到javaeye回贴的submit,只能不停地用“问题补充”。 <br /> <br />to mccxj : <br />你认为 <br />location.equals(other.location) <br />road.equals(other.road) <br />这样的比较正确吗?还是 <br /> <br />location.getName().equals(other.location.getName()) <br />road.getName().equals(other.road.getName()) <br /> <br />更好呢? <br />
©️2020 CSDN 皮肤主题: 点我我会动 设计师:白松林 返回首页