亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

ConcurrentHashMap 的值拋出 NullPointerException

ConcurrentHashMap 的值拋出 NullPointerException

神不在的星期二 2022-12-07 15:08:47
我正在維護使用ConcurrentHashMap.其他方法中有add和remove的操作。在下面的代碼中,在從地圖中收集了一些值后的某個時刻,它NullPointerException在執行時拋出synchronize(value)。public class MyClass{    private final Map<MyObj, Map<String, List<String>>> conMap = new ConcurrentHashMap<>();    //...    public void doSomthing((MyObj id){        List<Map<String, List<String>>> mapsList = new LinkedList<>();        for(MyObj objId: conMap.keySet()){                          if(objId.key1.equals(id.key1)){                mapsList.add(conMap.get(objId));            }        }        for(Map<String, List<String>> map: mapsList){            synchronized(map){                   // <-- NullPointerException here                //...            }    }    //...}我有一種感覺,也許在第一個循環的迭代過程中,記錄被刪除了。當行:mapsList.add(conMap.get(objId));正在執行,objId不再存在并mapsList添加 null,結果,在第二個循環期間NullPoinerException被拋出。還有其他原因可以得到這個例外嗎?
查看完整描述

1 回答

?
慕碼人2483693

TA貢獻1860條經驗 獲得超9個贊

您已經愛上了 Check-Then-Act 反模式。它意味著檢查條件(如密鑰的存在),然后對其采取行動(如調用get),忽略條件可能在其間發生變化的可能性。


因此,您在迭代時遇到了一個特定的鍵conMap.keySet(),但在您調用conMap.get(objId)時,該鍵可能不再位于映射中,返回時會報告這一點null。


強烈建議使用具有合適hashCode/equals實現的鍵類型,這樣您就無需遍歷整個地圖來查找匹配項,而是可以使用單個get(id).


但是,當您必須遍歷映射并需要值時,請遍歷條目集而不是鍵集。


public void doSomething(MyObj id){

    // see https://stackoverflow.com/q/322715/2711488

    List<Map<String, List<String>>> mapsList = new ArrayList<>();


    for(Map.Entry<MyObj, Map<String, List<String>>> e: conMap.entrySet()){              

        if(e.getKey().key1.equals(id.key1)){

            mapsList.add(e.getValue());

        }

    }


    for(Map<String, List<String>> map: mapsList){

        synchronized(map) {

            //...

        }

    }

}


查看完整回答
反對 回復 2022-12-07
  • 1 回答
  • 0 關注
  • 204 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號