第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

理解HashMap中equals和hashCode的工作原理

理解HashMap中equals和hashCode的工作原理

BIG陽(yáng) 2019-08-31 16:34:58
我有這個(gè)測(cè)試代碼:import java.util.*;class MapEQ {  public static void main(String[] args) {   Map<ToDos, String> m = new HashMap<ToDos, String>();   ToDos t1 = new ToDos("Monday");   ToDos t2 = new ToDos("Monday");   ToDos t3 = new ToDos("Tuesday");   m.put(t1, "doLaundry");   m.put(t2, "payBills");   m.put(t3, "cleanAttic");   System.out.println(m.size());} }class ToDos{  String day;  ToDos(String d) { day = d; }  public boolean equals(Object o) {      return ((ToDos)o).day == this.day; }// public int hashCode() { return 9; }}何時(shí)// public int hashCode() { return 9; }取消注釋m.size()返回2,當(dāng)它被注釋 時(shí),它返回三。為什么?
查看完整描述

3 回答

?
忽然笑

TA貢獻(xiàn)1806條經(jīng)驗(yàn) 獲得超5個(gè)贊

HashMap使用hashCode(),==并equals()用于條目查找。給定鍵的查找序列k如下:


使用k.hashCode()來(lái)確定條目存儲(chǔ)其斗,如果有的話

如果找到,對(duì)于k1該桶中的每個(gè)條目的密鑰,如果k == k1 || k.equals(k1),則返回k1的條目

任何其他結(jié)果,沒(méi)有相應(yīng)的條目

為了演示一個(gè)例子,假設(shè)我們想要?jiǎng)?chuàng)建一個(gè)HashMapwhere鍵,如果它們具有相同的整數(shù)值(由AmbiguousIntegerclass 表示),則它們?cè)谶壿嬌鲜堑葍r(jià)的。然后我們構(gòu)造一個(gè)HashMap,放入一個(gè)條目,然后嘗試覆蓋其值并按鍵檢索值。


class AmbiguousInteger {

    private final int value;


    AmbiguousInteger(int value) {

        this.value = value;

    }

}


HashMap<AmbiguousInteger, Integer> map = new HashMap<>();

// logically equivalent keys

AmbiguousInteger key1 = new AmbiguousInteger(1),

                 key2 = new AmbiguousInteger(1),

                 key3 = new AmbiguousInteger(1);

map.put(key1, 1); // put in value for entry '1'

map.put(key2, 2); // attempt to override value for entry '1'

System.out.println(map.get(key1));

System.out.println(map.get(key2));

System.out.println(map.get(key3));


Expected: 2, 2, 2

不要覆蓋hashCode()和equals():在默認(rèn)情況下的Java生成不同的hashCode()不同對(duì)象的值,因此HashMap使用這些值映射key1和key2成不同的桶。key3沒(méi)有相應(yīng)的桶,所以它沒(méi)有價(jià)值。


class AmbiguousInteger {

    private final int value;


    AmbiguousInteger(int value) {

        this.value = value;

    }

}


map.put(key1, 1); // map to bucket 1, set as entry 1[1]

map.put(key2, 2); // map to bucket 2, set as entry 2[1]

map.get(key1); // map to bucket 1, get as entry 1[1]

map.get(key2); // map to bucket 2, get as entry 2[1]

map.get(key3); // map to no bucket

Expected: 2, 2, 2

Output:   1, 2, null

hashCode()僅覆蓋: HashMap映射key1并key2進(jìn)入同一個(gè)存儲(chǔ)桶,但由于兩者key1 == key2和key1.equals(key2)檢查失敗,它們保持不同的條目,因?yàn)槟J(rèn)情況下equals()使用==check,它們引用不同的實(shí)例。key3失敗都==和equals()檢查對(duì)key1和key2,因此具有沒(méi)有對(duì)應(yīng)的值。


class AmbiguousInteger {

    private final int value;


    AmbiguousInteger(int value) {

        this.value = value;

    }


    @Override

    public int hashCode() {

        return value;

    }

}


map.put(key1, 1); // map to bucket 1, set as entry 1[1]

map.put(key2, 2); // map to bucket 1, set as entry 1[2]

map.get(key1); // map to bucket 1, get as entry 1[1]

map.get(key2); // map to bucket 1, get as entry 1[2]

map.get(key3); // map to bucket 1, no corresponding entry

Expected: 2, 2, 2

Output:   1, 2, null

equals()僅覆蓋: HashMap由于默認(rèn)值不同,將所有密鑰映射到不同的存儲(chǔ)桶hashCode()。==或者equals()檢查在這里是無(wú)關(guān)緊要的,因?yàn)樗麳ashMap永遠(yuǎn)不會(huì)達(dá)到需要使用它們的程度。


class AmbiguousInteger {

    private final int value;


    AmbiguousInteger(int value) {

        this.value = value;

    }


    @Override

    public boolean equals(Object obj) {

        return obj instanceof AmbiguousInteger && value == ((AmbiguousInteger) obj).value;

    }

}


map.put(key1, 1); // map to bucket 1, set as entry 1[1]

map.put(key2, 2); // map to bucket 2, set as entry 2[1]

map.get(key1); // map to bucket 1, get as entry 1[1]

map.get(key2); // map to bucket 2, get as entry 2[1]

map.get(key3); // map to no bucket

Expected: 2, 2, 2

Actual:   1, 2, null

覆蓋both hashCode()和equals():HashMapmaps key1,key2并覆蓋key3到同一個(gè)存儲(chǔ)桶中。==在比較不同的實(shí)例時(shí)檢查失敗,但是equals()檢查通過(guò),因?yàn)樗鼈兌季哂邢嗤闹?,并且被我們的邏輯視為“邏輯上等效”?/p>


class AmbiguousInteger {

    private final int value;


    AmbiguousInteger(int value) {

        this.value = value;

    }


    @Override

    public int hashCode() {

        return value;

    }


    @Override

    public boolean equals(Object obj) {

        return obj instanceof AmbiguousInteger && value == ((AmbiguousInteger) obj).value;

    }

}


map.put(key1, 1); // map to bucket 1, set as entry 1[1]

map.put(key2, 2); // map to bucket 1, set as entry 1[1], override value

map.get(key1); // map to bucket 1, get as entry 1[1]

map.get(key2); // map to bucket 1, get as entry 1[1]

map.get(key3); // map to bucket 1, get as entry 1[1]

Expected: 2, 2, 2

Actual:   2, 2, 2

如果hashCode()隨機(jī)怎么辦?:HashMap將為每個(gè)操作分配一個(gè)不同的存儲(chǔ)桶,因此您永遠(yuǎn)不會(huì)找到您之前輸入的相同條目。


class AmbiguousInteger {

    private static int staticInt;

    private final int value;


    AmbiguousInteger(int value) {

        this.value = value;

    }


    @Override

    public int hashCode() {

        return ++staticInt; // every subsequent call gets different value

    }


    @Override

    public boolean equals(Object obj) {

        return obj instanceof AmbiguousInteger && value == ((AmbiguousInteger) obj).value;

    }

}


map.put(key1, 1); // map to bucket 1, set as entry 1[1]

map.put(key2, 2); // map to bucket 2, set as entry 2[1]

map.get(key1); // map to no bucket, no corresponding value

map.get(key2); // map to no bucket, no corresponding value

map.get(key3); // map to no bucket, no corresponding value

Expected: 2, 2, 2

Actual:   null, null, null

如果hashCode()總是一樣的話怎么辦?:HashMap將所有鍵映射到一個(gè)大桶中。在這種情況下,您的代碼在功能上是正確的,但使用HashMap實(shí)際上是多余的,因?yàn)槿魏螜z索都需要在O(N)時(shí)間內(nèi)迭代該單個(gè)存儲(chǔ)桶中的所有條目(或Java 8的O(logN)),等效使用a List。


class AmbiguousInteger {

    private final int value;


    AmbiguousInteger(int value) {

        this.value = value;

    }


    @Override

    public int hashCode() {

        return 0;

    }


    @Override

    public boolean equals(Object obj) {

        return obj instanceof AmbiguousInteger && value == ((AmbiguousInteger) obj).value;

    }

}


map.put(key1, 1); // map to bucket 1, set as entry 1[1]

map.put(key2, 2); // map to bucket 1, set as entry 1[1]

map.get(key1); // map to bucket 1, get as entry 1[1]

map.get(key2); // map to bucket 1, get as entry 1[1]

map.get(key3); // map to bucket 1, get as entry 1[1]

Expected: 2, 2, 2

Actual:   2, 2, 2

如果equals總是假的怎么辦?:==當(dāng)我們將同一個(gè)實(shí)例與自身進(jìn)行比較時(shí)檢查通過(guò),但是否則失敗,equals檢查總是失敗key1,key2并且key3被認(rèn)為是“邏輯上不同”,并且映射到不同的條目,盡管它們?nèi)匀辉谕煌爸衕ashCode()。


class AmbiguousInteger {

    private final int value;


    AmbiguousInteger(int value) {

        this.value = value;

    }


    @Override

    public int hashCode() {

        return 0;

    }


    @Override

    public boolean equals(Object obj) {

        return false;

    }

}


map.put(key1, 1); // map to bucket 1, set as entry 1[1]

map.put(key2, 2); // map to bucket 1, set as entry 1[2]

map.get(key1); // map to bucket 1, get as entry 1[1]

map.get(key2); // map to bucket 1, get as entry 1[2]

map.get(key3); // map to bucket 1, no corresponding entry

Expected: 2, 2, 2

Actual:   1, 2, null

好的,如果equals現(xiàn)在總是如此?:你基本上是說(shuō)所有對(duì)象都被認(rèn)為與另一個(gè)對(duì)象“在邏輯上等同”,所以它們都映射到同一個(gè)桶(由于相同hashCode()),相同的條目。


class AmbiguousInteger {

    private final int value;


    AmbiguousInteger(int value) {

        this.value = value;

    }


    @Override

    public int hashCode() {

        return 0;

    }


    @Override

    public boolean equals(Object obj) {

        return true;

    }

}


map.put(key1, 1); // map to bucket 1, set as entry 1[1]

map.put(key2, 2); // map to bucket 1, set as entry 1[1], override value

map.put(new AmbiguousInteger(100), 100); // map to bucket 1, set as entry1[1], override value

map.get(key1); // map to bucket 1, get as entry 1[1]

map.get(key2); // map to bucket 1, get as entry 1[1]

map.get(key3); // map to bucket 1, get as entry 1[1]

Expected: 2, 2, 2

Actual:   100, 100, 100


查看完整回答
反對(duì) 回復(fù) 2019-08-31
?
慕碼人8056858

TA貢獻(xiàn)1803條經(jīng)驗(yàn) 獲得超6個(gè)贊

你已經(jīng)超越equals而沒(méi)有覆蓋hashCode。您必須確保equals對(duì)于兩個(gè)對(duì)象返回true的所有情況,hashCode返回相同的值。哈希碼是一個(gè)代碼,如果兩個(gè)對(duì)象相等則必須相等(反之不必為真)。當(dāng)您將硬編碼值設(shè)置為9時(shí),您再次滿足合同。


在哈希映射中,僅在哈希桶中測(cè)試相等性。你的兩個(gè)星期一對(duì)象應(yīng)該是相同的,但是因?yàn)樗鼈兎祷夭煌墓4a,所以equals甚至不調(diào)用該方法來(lái)確定它們的相等性 - 它們被直接放入不同的桶中,甚至不考慮它們相等的可能性。


查看完整回答
反對(duì) 回復(fù) 2019-08-31
?
森林海

TA貢獻(xiàn)2011條經(jīng)驗(yàn) 獲得超2個(gè)贊

我不能強(qiáng)調(diào)你應(yīng)該閱讀Effective Java中的第3章(警告:pdf鏈接)。在該章中,您將了解有關(guān)覆蓋方法的所有信息Object,特別是有關(guān)equals合同的信息。喬什布洛赫有一個(gè)很好的方法來(lái)覆蓋equals你應(yīng)該遵循的方法。它將幫助您了解您應(yīng)該使用的原因,equals而不是==您equals方法的特定實(shí)現(xiàn)。


希望這可以幫助。請(qǐng)仔細(xì)閱讀。(至少是前幾個(gè)項(xiàng)目......然后你會(huì)想要閱讀其余的內(nèi)容:-)。




查看完整回答
反對(duì) 回復(fù) 2019-08-31
  • 3 回答
  • 0 關(guān)注
  • 809 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)