灰太狼大王讲java之hashcode()方法

来源:互联网 发布:c语言求1到n的和函数 编辑:程序博客网 时间:2024/04/28 05:15

       一开始接触到hashcode()方法时真有点理解不了,找了点资料看看啊,还是觉得不深入。等到集合的内容都过了一遍时豁然觉得开朗起来,原因是对集合有了一个全面的认识,hashcode()方法自然也容易理解起来。所以,灰太狼大王建议如果你对hashcode()方法还是有点疑惑,不要在这钻牛角尖,继续深入学习下去,一定会有质的突破。

     在仔细分析前,灰太狼大王希望你去看本大王的另一篇博文《灰太狼大王讲java之集合框架》,不用从头到尾都看完,只需看看那两张图,对结合有一个基本的认识即可。java中的集合分为两类,一类元素可以重复(List),另一类元素不可以重复(如Set)。元素不可以重复的集合底层是如何实现的呢?学习字符串时,我们都接触过equals()方法,Object类中定义了equals()方法,它判断的是两个引用的地址是否相同,而String又重写(Override)此方法,判断传入的内容是否相同。如果判断元素是否相同用equals()方法,是否可行?答案是去你的吧,如果集合中的元素很多,equals()一个一个的比较下来,它肯定不服,是你你服吗?那怎么办?hashcode()就拯救世界了。哈希算法也称为散列算法,将数据依特定算法直接指定到一个地址上,当集合要添加新的元素时,首先调用这个元素的hashCode方法,判断地址是否一样,如果不一样把元素直接加进去,如果不一样再调用equals()判断二者内容是否一样,如果一样返回true,则认为两个元素重复了,不加进去。

     来看一个示例程序:

package com.yawanglazi;

import java.util.HashSet;

public class HashSetTest
{
    public static void main(String[] args)
    {
      HashSet set=new HashSet();
      Student s1 = new Student("Gray Wolf the King");
      Student s2 = new Student(" Gray Wolf the KingKingGray Wolf the KingGray Wolf the King");
      set.add(s1);
      set.add(s2);
      System.out.println(set);
    }
}

 class Student
{
    String name;
    
    public Student(String  name)
    {
        this.name=name;
    }
}


程序输出为:[com.yawanglazi.Student@4b6e3f87, com.yawanglazi.Student@188edd79]

重写hashcode()方法和equals()方法后的程序如下:

package com.yawanglazi;

import java.util.HashSet;

public class HashSetTest
{
    public static void main(String[] args)
    {
      HashSet set=new HashSet();
      Student s1 = new Student("Gray Wolf the King ");
      Student s2 = new Student("Gray Wolf the King ");
      set.add(s1);
      set.add(s2);
      System.out.println(set);
    }
}

 class Student
{
    public int hashCode()
    {
      //  final int prime = 31;        这里是程序自动生成的,本大王不用这个,注释掉
      //  int result = 1;
      //  result = prime * result + ((name == null) ? 0 : name.hashCode());
      //  return result;

     this.name.hashcode();//这里你就一目了然了,s1和s2返回了相同的hashcode()

    }

    public boolean equals(Object obj)
    {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Student other = (Student) obj;
        if (name == null)
        {
            if (other.name != null)
                return false;
        }
        else if (!name.equals(other.name))
            return false;
        return true;
    }

    String name;
    
    public Student(String  name)
    {
        this.name=name;
    }
}

程序输出为:[com.yawanglazi.Student@c1a1ce08]

总结:

      重写hashcode()方法和equals()方法前,输出为两个,s1和s2虽然拥有不同的地址,但是却具有不同的哈希码。重写后,s1和s2的拥有了一样的哈希码,故调用了equals()方法继续对二者进行比较。为什么这样做,因为在实际开发环境下我们都都认为只要两者内容一样就是相同的元素,而不去计较它在内存中的地址是否相同。