编写简单的hashCode方法

为什么要编写hashCode方法

  hashCode在平时不常自己去编写,但是在真正高质量的代码中却是必不可少的。

  看看Java中的Object对hashCode方法的描述:

    1.返回对象的哈希码,是为了提高哈希表的性能,例如java.util.HashTable

    2.同一个对象多次调用hashCode方法时,必须一致的返回相同的整数

    3.若两个对象相等,则调用hashCode方法的时候必须返回相同的整数

不编写hashCode方法出现的情况

  下面有这样的一个实体类:

/**

 * @class User

 * @introduction 实体类

 * @author Ray_xujianguo

 */

public class User {

    private String name;                //姓名

    private int age;                    //年龄

    private long friendNumber;            //朋友数目

    private float cash;                    //现金

    private double wealth;                //财富

    private boolean isMarry;            //是否已婚

    

    //无参数构造方法

    public User() {}

    

    //有参数构造方法

    public User(String name, int age, long friendNumber, float cash, double wealth, boolean isMarry) {

        this.name = name;

        this.age = age;

        this.friendNumber = friendNumber;

        this.cash = cash;

        this.wealth = wealth;

        this.isMarry = isMarry;

    }

    

    @Override

    public boolean equals(Object object) {

        if(object instanceof User) {

            User user = (User)object;

            if(user.getName().equals(name) && 

                    user.getAge() == age && 

                    Long.compare(user.getFriendNumber(), friendNumber) == 0 &&

                    Float.compare(user.getCash(), cash) == 0 &&

                    Double.compare(user.getWealth(), wealth) == 0 &&

                    user.isMarry() == isMarry) {

                return true;

            } else {

                return false;

            }

        } else {

            return false;

        }

    }



    //getter and setter method

    public String getName() {

        return name;

    }



    public void setName(String name) {

        this.name = name;

    }



    public int getAge() {

        return age;

    }



    public void setAge(int age) {

        this.age = age;

    }



    public long getFriendNumber() {

        return friendNumber;

    }



    public void setFriendNumber(long friendNumber) {

        this.friendNumber = friendNumber;

    }



    public float getCash() {

        return cash;

    }



    public void setCash(float cash) {

        this.cash = cash;

    }



    public double getWealth() {

        return wealth;

    }



    public void setWealth(double wealth) {

        this.wealth = wealth;

    }



    public boolean isMarry() {

        return isMarry;

    }



    public void setMarry(boolean isMarry) {

        this.isMarry = isMarry;

    }

}

  这个实体类是重写了equals方法的,现在我们试图将其放进Map中,再将其拿出来。

    @Test

    public void testHashCode() {

        Map<User, String> map = new HashMap<User, String>();

        map.put(new User("xujianguo", 21, (long)1000, (float)12.5, (double)6000.25, false), "admin");

        System.out.println(map.get(new User("xujianguo", 21, (long)1000, (float)12.5, (double)6000.25, false)));

    }

   这个的map存进去了一个User和String啊,根据这个User怎么拿不到呢,原因是因为这两个User的hashCode不一样,说到根本的东西就是调用hashCode方法没有返回一致的哈希码下面我们就来说说怎么编写hashCode方法。

编写hashCode方法

  1.把某个非零的常数值,保存在一个名为result的int类型的常量中

  2.属性域f哈希码c的计算

  • 如果是boolean类型,true为1,false为0
  • 如果是byte、char、short和int类型,强制为int的值
  • 如果是long类型,计算(int)(f^(f>>32))
  • 如果是float类型,计算Float.floatToIntBits(f)
  • 如果是double类型,计算Double.doubleToLongBits(f),再按照long的方法进行计算
  • 如果是引用类型,则调用其hashCode方法(假设其hashCode满足你的需求)

  3.代入公式result = result * 31 + c

  4.返回result

  现在针对这User类来编写hashCode方法:

    @Override

    public int hashCode() {

        int result = 17;

        result = 37 * result + name.hashCode();

        result = 37 * result + age;

        result = 37 * result + (int)(friendNumber^(friendNumber>>32));

        result = 37 * result + Float.floatToIntBits(cash);

        result = 37 * result + (int)(Double.doubleToLongBits(wealth)^(Double.doubleToLongBits(wealth)>>32));

        result = 37 * result + (isMarry ? 1 : 0);

        return result;

    }

  加入了这个hashCode方法后,上面那个testHashCode方法就可以成功通过key拿出value了。

你可能感兴趣的:(HashCode)