java:equals与hascode( )

转载 2016年05月31日 14:19:04

Java中的equals方法和hashcode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要重写这两个方法。

1.区别

eqauls()和hashcode()方法是用来在同一类中做比较用的,尤其是在容器里如set存放同一类对象时用来判断放入的对象是否重复。这里我们首先要明白一个问题:

1,equals()相等的两个对象,hashcode()一定相等,equals()不相等的对象,却并不能证明他们的hashcode()不相等。换句话说,equals()方法不相等的两个对象,hashcode() 有可能相等。(我的理解是由于哈希码在生成的时候产生冲突造成的)
2,在这里hashcode() 就好比字典里每个字的索引,equals()好好比比较的是字典里同一个字下的不同词语。就好像在字典里面查“自”这个字下的两个词语“自己”和“自发”。
3,反过来,hashcode不等,一定能推出equals()也不等;hashcode()相等,equals()可能相等,也可能不相等。
4,在object类中,hashcode()方法是本地方法,返回的是对象的地址值,而object类中的equals()方法比较的也是两个对象的地址值,如果equals()相等,说明两个对象地址值也相等,当然hashcode() 也就相等了。

2.hashcode()的用法

1,有人发明了一种哈希算法来提高从集合中查找元素的效率,这种方式将集合分成若干个存储区域,每个对象可以计算出一个哈希码,可以将哈希码分组(使用不同的hash函数来计算的),每组分别对应某个存储区域,根据一个对象的哈希吗就可以确定该对象应该存储在哪个区域HashSet就是采用哈希算法存取对象的集合,它内部采用对某个数字n进行取余(这种的hash函数是最简单的)的方式对哈希码进行分组和划分对象的存储区域;
2,Object类中定义了一个hashCode()方法来返回每个Java对象的哈希码,当从HashSet集合中查找某个对象时,Java系统首先调用对象的hashCode()方法获得该对象的哈希码表,然后根据哈希吗找到相应的存储区域,最后取得该存储区域内的每个元素与该对象进行equals方法比较;这样就不用遍历集合中的所有元素就可以得到结论,可见,HashSet集合具有很好的对象检索性能,
3,但是,HashSet集合存储对象的效率相对要低些,因为向HashSet集合中添加一个对象时,要先计算出对象的哈希码和根据这个哈希码确定对象在集合中的存放位置为了保证一个类的实例对象能在HashSet正常存储,要求这个类的两个实例对象用equals()方法比较的结果相等时,他们的哈希码也必须相等;也就是说,如果obj1.equals(obj2)的结果为true,那么以下表达式的结果也要为true:
obj1.hashCode() == obj2.hashCode()

换句话说:当我们重写一个对象的equals方法,就必须重写他的hashCode方法,不过不重写他的hashCode方法的话,Object对象中的hashCode方法始终返回的是一个对象的hash地址,而这个地址是永远不相等的。所以这时候即使是重写了equals方法,也不会有特定的效果的,因为hashCode方法如果都不想等的话,就不会调用equals方法进行比较了,所以没有意义了。

3.例子

package com.weijia.demo;

public class RectObject {
    public int x;
    public int y;
    public RectObject(int x,int y){
        this.x = x;
        this.y = y;
    }
    @Override
    public int hashCode(){
        final int prime = 31;
        int result = 1;
        result = prime * result + x;
        result = prime * result + y;
        return result;
    }
    @Override
    public boolean equals(Object obj){
        if(this == obj)
            return true;
        if(obj == null)
            return false;
        if(getClass() != obj.getClass())
            return false;
        final RectObject other = (RectObject)obj;
        if(x != other.x){
            return false;
        }
        if(y != other.y){
            return false;
        }
        return true;
    }
}

4.重要的点

如果我们将对象的属性值参与了hashCode的运算中,在进行删除的时候,就不能对其属性值进行修改,否则会出现严重的问题。

相关文章推荐

hascode和equals为什么要同时复写—Java源码中的奥秘

在很多编程手册和技术推送文章中,都要求我们在创建一个类型的对象时候,强烈建议实现的其中的几个方法,一般包括: 1.  toString() 2. equals()3. hashcode()  此...
  • muskter
  • muskter
  • 2017年07月28日 10:03
  • 133

effective_java之一:覆写 equals 和 hasCode 方法

提升下自己的表达及总结能力,也许若干年后可以去做一名合格的讲师~~~ 一、覆写equals方法 为什么要覆写equals方法呢?覆写的原则是什么呢?原因以下: 有时候做到 两个实例对象在 逻辑上是否相...
  • klov001
  • klov001
  • 2013年11月16日 14:39
  • 901

Java equals与hasCode详解

以下是关于HashCode的官方文档定义: [plain] view plaincopy hashcode方法返回该对象的哈希码值。支持该方法是为哈希表提供一些优点,例如,ja...

java中的hasCode与equals理解(转载) .

1. 首先equals()和hashcode()这两个方法都是从object类中继承过来的。  equals()方法在object类中定义如下:    public boolean equals(...

java中的hasCode与equals理解(转载)

1. 首先equals()和hashcode()这两个方法都是从object类中继承过来的。  equals()方法在object类中定义如下:    public boolean equals(Ob...
  • sg_0504
  • sg_0504
  • 2015年03月10日 13:49
  • 344

联合主键实现Serializable接口,同时重写equals和hasCode方法 的原因和步骤

关于联合主键 联合主键为什么要重写equals方法和hashCode方法,是为了保证唯一性 1、在数据库保证唯一性是使用的联合主键 2、把一系列的对象放到内存的时候,为了区分同名对象,数据库是使...

java_equals用法

  • 2014年06月27日 14:13
  • 624B
  • 下载

Java中的==和equals区别

  • 2013年01月30日 10:23
  • 15KB
  • 下载

java 中的==和equals比较

概述: A.==可用于基本类型和引用类型:当用于基本类型时候,是比较值是否相同;当用于引用类型的时候,是比较对象是否相同。 B.对于String a = “a”; Integer b = 1;这种...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java:equals与hascode( )
举报原因:
原因补充:

(最多只允许输入30个字)