Java中重写equals()方法时注意点
Java中重寫equals()方法時(shí)注意點(diǎn)
一直說,重寫一個(gè)對象的equals()方法時(shí)我們必須重寫HashCode()方法,但是如果我們不重寫呢?會(huì)有什么影響呢?
首先看一下,什么情況下我們需要重寫equals()方法?
一個(gè)新定義的對象,如果需要比較時(shí),這時(shí)候我們需要重寫一下equals()方法,否則,用jdk自定義的equals()的話,會(huì)造成只要不是一個(gè)內(nèi)存地址就不返回相等。
先定義一個(gè)類:
public class HeroStat {private final int strength;private final int intelligence;private final int luck;// All constructors must be private. private HeroStat(int strength, int intelligence, int luck) {this.strength = strength;this.intelligence = intelligence;this.luck = luck; }// Static factory method to create new instances. public static HeroStat valueOf(int strength, int intelligence, int luck) {return new HeroStat(strength, intelligence, luck); }public int getStrength() {return strength; }public int getIntelligence() {return intelligence; }public int getLuck() {return luck; }}看下比較的代碼:
public static void main(String[] args) {HeroStat statA = HeroStat.valueOf(10, 5, 0);HeroStat statB = HeroStat.valueOf(10, 5, 0);HeroStat statC = HeroStat.valueOf(5, 1, 8);LOGGER.info(statA.toString());LOGGER.info("Is statA and statB equal : {}", statA.equals(statB));LOGGER.info("Is statA and statC equal : {}", statA.equals(statC)); }這里如果我們沒有重寫equals方法,則輸出A.equals(B)肯定返回false,因?yàn)楸容^的是==,如果重寫了,則可以返回為true。
那么,如果我們只重寫equals()方法呢?
@Override public boolean equals(Object obj) { if (this == obj) {return true; } if (obj == null) {return false; } if (getClass() != obj.getClass()) {return false; } HeroStat other = (HeroStat) obj; if (intelligence != other.intelligence) {return false; } if (luck != other.luck) {return false; } if (strength != other.strength) {return false; } return true; }像這樣,則可以滿足我們的需求,比較這個(gè)對象的屬性,并且滿足java規(guī)定的equals()方法的5個(gè)特性:
1,對稱性,A.equals(B)==true B.equals(A)也一定為true
2,反射性 A.equals(A) 一定為true
3,類推性 A.equals(B)==true B.equals(C)==true,則A.equals(C)==true
4,一致性 A.equals(B)==true時(shí),不管調(diào)用多少次都應(yīng)該為true,不會(huì)改變
5,非空性 A.equals(null)一定為false。
這樣看起來一點(diǎn)問題都沒有了,雖然我們沒有重寫hashCode()方法,但是已經(jīng)ok了。
但是,真的是這樣嗎?
我們試著使用HashSet和HashMap這2個(gè)類。
看代碼:
public static void main(String[] args) {HeroStat statA = HeroStat.valueOf(10, 5, 0);HeroStat statB = HeroStat.valueOf(10, 5, 0);HeroStat statC = HeroStat.valueOf(5, 1, 8);Set<HeroStat> set = new HashSet<>();set.add(statA);set.add(statB);set.add(statC);System.out.println(set); }console 輸出:
[HeroStat [strength=10, intelligence=5, luck=0], HeroStat [strength=10, intelligence=5, luck=0], HeroStat [strength=5, intelligence=1, luck=8]]我們發(fā)現(xiàn),set中把3個(gè)對象全部插入進(jìn)去了,但是statA和statB其實(shí)是equals返回為true的。
這里就暴露出問題了,如果不重寫hashCode()方法,則有關(guān)hashCode的地方都會(huì)有問題,比如HashSet,HashMap。
那么如果要重寫hashCode()方法時(shí),我們要注意什么呢?
A.equals(B) 則必須使得 A.hashCode() == B.hashCode();
如果 A.hashCode() != B.hashCode() 則 A.equals(B) 一定為false。
與50位技術(shù)專家面對面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的Java中重写equals()方法时注意点的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: BUG总结—Navicat连接Mysql
- 下一篇: Bug整理——Spring boot 执