重写了equals方法为何需要重写 hashCode

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了重写了equals方法为何需要重写 hashCode相关的知识,希望对你有一定的参考价值。

讲到容器时说重写了equals方法需要重写 hashCode 以前讲到对象时 判断两对象是否相等只需equals没重写hashCode
重写了equals方法需要重写 hashCode ()是不是只是在所有容器中都那么写 只限定在容器中还需比较hashCode

equals方法本身就是对较两个对象hashCode对应的内存模型和值是否相同。如果你只重写了equals方法,那你就得思考如果不重写hashCode方法,怎么去判断这两个对象是否相等。而hashCode本身的对象在JVM中的分配信息有关,而这个分配工作并不是你去指定的,而是由对象生成时,JVM本身去维护和管理的。并不是一定要重写这两个方法,关键是看你想干什么。比如说重写toString方法,如果你不重写,如果System.out.println(a);//a 是一个对象,则输出的值就是对象的hashCode,哈希本身是一种编码格式。如果要深究这些,建议看些算法的书本。底层的实现基本完全依赖于算法和数据结构。 参考技术A 为了使相同值的对象其键可以指向相同的存储空间之中,有点像hashmap的使用,这样数据量大的时候就会节省了内存空间。本回答被提问者采纳

Hibernate中用到联合主键的使用方法,为何要序列化,为何要重写hashcode 和 equals 方法

联合主键用Hibernate注解映射方式主要有三种: 

第一、将联合主键的字段单独放在一个类中,该类需要实现java.io.Serializable接口并重写equals和hascode,再将该类注解为@Embeddable,最后在主类中(该类不包含联合主键类中的字段)保存该联合主键类的一个引用,并生成set和get方法,并将该引用注解为@Id

package com.test.entity;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Embeddable;

@Embeddable
public class TestPk implements Serializable{
    private static final long serialVersionUID = 1L;
    @Column(name="id")
    private int id;
    @Column(name="sid")
    private String sid;

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getSid() {
        return sid;
    }
    public void setSid(String sid) {
        this.sid = sid;
    }
}

package com.test.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Table(name="test")
@Entity
public class Test1 {
    @Column(name="date")
    private String date;
    @Id
    private TestPk testPk;
    public String getDate() {
        return date;
    }
    public void setDate(String date) {
        this.date = date;
    }
    public TestPk getTestPk() {
        return testPk;
    }
    public void setTestPk(TestPk testPk) {
        this.testPk = testPk;
    }
    

}





第二、将联合主键的字段单独放在一个类中,该类需要实现java.io.Serializable接口并重写equals和hascode,最后在主类中(该类不包含联合主键类中的字段)保存该联合主键类的一个引用,并生成set和get方法,并将该引用注解为@EmbeddedId

package com.test.entity;

import java.io.Serializable;

import javax.persistence.Column;

public class TestPk implements Serializable{
    private static final long serialVersionUID = 1L;
    @Column(name="id")
    private int id;
    @Column(name="sid")
    private String sid;

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getSid() {
        return sid;
    }
    public void setSid(String sid) {
        this.sid = sid;
    }
}
package com.test.entity;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Table;
@Table(name="test")
@Entity
public class Test1 {
    @Column(name="date")
    private Date date;
    @EmbeddedId
    private TestPk testPk;
    public Date getDate() {
        return date;
    }
    public void setDate(Date date) {
        this.date = date;
    }
    public TestPk getTestPk() {
        return testPk;
    }
    public void setTestPk(TestPk testPk) {
        this.testPk = testPk;
    }
    

}



第三、将联合主键的字段单独放在一个类中,该类需要实现java.io.Serializable接口并要重写equals和hashcode.最后在主类中(该类包含联合主键类中的字段)将联合主键字段都注解为@Id,并在该类上方将上这样的注解:@IdClass(联合主键类.class)

package com.test.entity;

import java.io.Serializable;

import javax.persistence.Column;

public class TestPk implements Serializable{
    private static final long serialVersionUID = 1L;
    @Column(name="id")
    private int id;
    @Column(name="sid")
    private String sid;

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getSid() {
        return sid;
    }
    public void setSid(String sid) {
        this.sid = sid;
    }
}
package com.test.entity;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.Table;
@Table(name="test")
@IdClass(TestPk.class)
@Entity
public class Test1 {
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getSid() {
        return sid;
    }
    public void setSid(String sid) {
        this.sid = sid;
    }
    @Column(name="date")
    private Date date;
    @Id
    private int id;
    @Id
    private String sid;
    public Date getDate() {
        return date;
    }
    public void setDate(Date date) {
        this.date = date;
    }
    
    

}



 

序列化原因 :如果多个该类对象同时放入内存中,在一个集群系统中,

其中一台服务器当机了,需要将内存中对象写到其它服务器。

同时,如果该服务器内存以满,需要用虚拟内存,这就需要序列化后才能写到硬盘上

 

重写hashCode()和equal()方法 原因 : 这是为了保证对象唯一性的。

将许多对象放在内存中,他们之间用什么区分呢?数据库中用那个主键来区分的,

因此在这儿应该重写hashCode()和equal()方法

转自CSDN:  https://blog.csdn.net/u014520047/article/details/52302463






























































































































































































以上是关于重写了equals方法为何需要重写 hashCode的主要内容,如果未能解决你的问题,请参考以下文章

HashMap中使用自定义类作为Key时,为何要重写HashCode和Equals方法

【彻底理解】 为啥重写equals()方法为啥要重写hashCode()方法

为啥重写equals方法,一定要重写HashCode方法?

关于equals与hashcode的重写

为什么在重写 equals 方法的时候需要重写 hashCode 方法?

重写hashcode和equals怎么重写