java 判断两个对象是否相等 equals 和 hashcode() 的必要性

转载 2012年05月06日 13:08:47

只有用到Hashtable、HashMap、HashSet、LinkedHashMap等时才要注意hashcode,其他地方hashcode无用。(这么理解不一定对)

判断两个对象是否相等是否要求hashcode() 相等,下边的说法是否对

在java的集合中,判断两个对象是否相等的规则是:
1),判断两个对象的hashCode是否相等
      如果不相等,认为两个对象也不相等,完毕
      如果相等,转入2)
(这一点只是为了提高存储效率而要求的,其实理论上没有也可以,但如果没有,实际使用时效率会大大降低,所以我们这里将其做为必需的。后面会重点讲到这个问题。)
2),判断两个对象用equals运算是否相等
      如果不相等,认为两个对象也不相等
      如果相等,认为两个对象相等(equals()是判断两个对象是否相等的关键)

 

我个人感觉上边的说法是   hashset 判定元素是否重复的规则(因为hashset不允许元素重复)

而非Hashtable、HashMap、HashSet、LinkedHashMap在代码中调用equals,就可以判断他们是否相等了

 

看一下下边的例子

 class Name   
{   
    private String first;    
    private String last;    
       
    public Name(String first, String last)    
    {    
        this.first = first;    
        this.last = last;    
    }    
  
    public boolean equals(Object o)    
    {    
        if (this == o)    
        {    
            return true;    
        }    
           
    if (o.getClass() == Name.class)    
        {    
            Name n = (Name)o;    
            return n.first.equals(first)    
                && n.last.equals(last);    
        }    
        return false;    
    }    
}   
  
public class HashSetTest   
{   
    public static void main(String[] args)   
    {    
        Set<Name> s = new HashSet<Name>();   
        s.add(new Name("abc", "123"));   
        System.out.println(   
            s.contains(new Name("abc", "123")));   
    }   
}   

上面程序中向 HashSet 里添加了一个 new Name("abc", "123") 对象之后,立即通过程序判断该 HashSet 是否包含一个 new Name("abc", "123") 对象。粗看上去,很容易以为该程序会输出 true。

实际运行上面程序将看到程序输出 false,这是因为 HashSet 判断两个对象相等的标准除了要求通过 equals() 方法比较返回 true 之外,还要求两个对象的hashCode() 返回值相等。而上面程序没有重写 Name 类的 hashCode() 方法,两个 Name 对象的 hashCode() 返回值并不相同,因此 HashSet 会把它们当成 2 个对象处理,因此程序返回 false。

由此可见,当我们试图把某个类的对象当成 HashMap 的 key,或试图将这个类的对象放入 HashSet 中保存时,重写该类的 equals(Object obj) 方法和 hashCode() 方法很重要,而且这两个方法的返回值必须保持一致:当该类的两个的 hashCode() 返回值相同时,它们通过 equals() 方法比较也应该返回 true。通常来说,所有参与计算 hashCode() 返回值的关键属性,都应该用于作为 equals() 比较的标准。
如下程序就正确重写了 Name 类的 hashCode() 和 equals() 方法,程序如下:

Java代码
class Name    
{    
    private String first;   
    private String last;   
    public Name(String first, String last)   
    {    
        this.first = first;    
        this.last = last;    
    }    
    // 根据 first 判断两个 Name 是否相等   
    public boolean equals(Object o)    
    {    
        if (this == o)    
        {    
            return true;    
        }    
        if (o.getClass() == Name.class)    
        {    
            Name n = (Name)o;    
            return n.first.equals(first);    
        }    
        return false;    
    }    
        
    // 根据 first 计算 Name 对象的 hashCode() 返回值   
    public int hashCode()    
    {    
        return first.hashCode();    
    }   
  
    public String toString()    
    {    
        return "Name[first=" + first + ", last=" + last + "]";    
    }    
 }     
    
public class HashSetTest2    
 {    
    public static void main(String[] args)    
    {    
        HashSet<Name> set = new HashSet<Name>();    
        set.add(new Name("abc" , "123"));    
        set.add(new Name("abc" , "456"));    
        System.out.println(set);    
    }    
}    

        上面程序中提供了一个 Name 类,该 Name 类重写了 equals() 和 toString() 两个方法,这两个方法都是根据 Name 类的 first 实例变量来判断的,当两个 Name 对象的 first 实例变量相等时,这两个 Name 对象的 hashCode() 返回值也相同,通过 equals() 比较也会返回 true。

程序主方法先将第一个 Name 对象添加到 HashSet 中,该 Name 对象的 first 实例变量值为"abc",接着程序再次试图将一个 first 为"abc"的 Name 对象添加到 HashSet 中,很明显,此时没法将新的 Name 对象添加到该 HashSet 中,因为此处试图添加的 Name 对象的 first 也是" abc",HashSet 会判断此处新增的 Name 对象与原有的 Name 对象相同,因此无法添加进入,程序在①号代码处输出 set 集合时将看到该集合里只包含一个 Name 对象,就是第一个、last 为"123"的 Name 对象。

 

HashSet 底层采用 HashMap 来保存所有元素,保存搭配HashMap的key中,所义HashMap的key判断key是否相等也是从hashcode和equals是否相等判断

 

转自 http://blog.csdn.net/willielee/article/details/5804463

判断两个对象是否相等,为什么必须同时重写equals()和hashcode()方法

hashCode 顾名思义是一个“散列值码” 散列值,并不能表现其唯一性,但是有离散性,其意义在于类似于进行hashMap等操作时,加快对象比较的速度,进而加快对象搜索的速度。 hashC...
  • yangmeijing
  • yangmeijing
  • 2015年11月26日 10:40
  • 1458

Java常考面试题6 equals相同的对象对于的hashCode是否相等?

equals和hashcode的关系
  • HZ_LIZX
  • HZ_LIZX
  • 2017年02月09日 17:49
  • 2071

hashcode()和equals()及HashSet判断对象相等

hashcode()和equals()及HashSet判断对象相等。 1. 首先equals()和hashcode()这两个方法都是从object类中继承过来的。 public boolean e...
  • hudashi
  • hudashi
  • 2011年11月07日 18:34
  • 5316

Java中“equals比较为true,那么hashcode就一定相等”这条真理探秘!

从刚接触java时候在面试时就时常遇到面试官问这样的问题:equals相等那么hashcode相等吗?也一直没有怀疑过这个逻辑的正确性。直道上个月,公司一个技术主管居然说:equals相等hashco...
  • liujian19790518
  • liujian19790518
  • 2011年05月17日 14:57
  • 3255

Java中如何判断两个对象是否相等(Java equals and ==)

原文:https://www.dutycode.com/post-140.html 如何判断两个对象相等,这个问题实际上可以看做是如何对equals方法和hashcode方法的理解。 ...
  • u013063153
  • u013063153
  • 2017年12月15日 02:16
  • 622

JAVA--HashCode 基础(判断对象是否相等)

HashCode基础 hashCode在JAVA中,代表了对象的一种特征。不同的对象哈希码是不同的。 哈希码是一种数据结构算法,在JAVA中,常见的哈希码算法获取到的哈希码具体值是怎么获取到的呢? 来...
  • qq_25223941
  • qq_25223941
  • 2015年11月18日 13:35
  • 3888

深入java的equals方法,怎么比较两个对象的内容是否相等?对象的内容指的是什么?

检查对象是否相等关系运算符==和!=也适用于所有对象,但它们的含义通常会使初涉Java领域的人找不到北。下面是一个例子://: Equivalence.javapublic class Equival...
  • flash59
  • flash59
  • 2007年06月28日 14:47
  • 1486

两个对象用equals方法比较为true,它们的Hashcode值相同吗?

两个对象用equals方法比较为true,它们的Hashcode值相同吗?        答:不一定相同。正常情况下,因为equals()方法比较的就是对象在内存中的值,如果值相同,那么Hash...
  • chwshuang
  • chwshuang
  • 2015年07月18日 17:17
  • 5029

java map 里面判断相等的hashcode方法

java中的每个对象都有一个唯一的hashcode与它对应,就跟一个地址一样。两个相同的字符串hashcode值也是一样。 在程序中,我们碰到了需要判断名字变种是否相等的问题。比如abc型的...
  • enthusiastic513
  • enthusiastic513
  • 2016年03月23日 22:44
  • 1085

判断两个对象内容相等与equals方法

判断两个对象内容相等 不能直接调用Object类里的equals方法,将equals方法写到Object类当中是让所有对象都拥有equals方法,,它的目的是给开发者重写的,不然其方法实现的功能与’...
  • qq_27485935
  • qq_27485935
  • 2015年04月30日 17:12
  • 3294
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java 判断两个对象是否相等 equals 和 hashcode() 的必要性
举报原因:
原因补充:

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