為什么要編寫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了。