說說java中傳容器某些狀況下失效

   樓主今天寫個方法移除map集合中的空值,遇到個問題,就是對容器操做後,發現失效了;先上代碼java

public static void removeValueNullAndEmpty(Map<String,String> A) {
        Map<String,String> B = new HashMap<>();
        for(String key : B.keySet()){
            if(A.get(key) != null || !"".equals(A.get(key))){
                B.put(key, A.get(key));
            }
        }
        A=B;
    }
public static void main(String[] args) {
        Map<String,String> B = new HashMap<>();
        B.put("c", "3");
        B.put("d", "");
        B.put("e", null);
        removeValueNullAndEmpty(B);
        System.out.println(B);
}

就是這麼個操做,結果固然很尷尬;函數

{c=3, d=, e=null}

怎麼回事呢?這就要說到函數的調用了,在main函數調用removeValueNullAndEmpty的時候,保存現場,保存了B的地址;咱們姑且看作addressB吧,也就是說main函數任務B = addressB;而後就把addressB傳給了removeValueNullAndEmpty方法,而removeValueNullAndEmpty方法的一系列處理其實並無改變addressB這個地址指向的空間內的任何數據;而是簡單的把B這個字面量指向的地址換成了addressB;而後結束了removeValueNullAndEmpty方法;在此以後,回到main方法,而main方法依然認爲B = addressB,爲何呢?這是由於咱們在removeValueNullAndEmpty方法中改變的那個字面量B已經隨着removeValueNullAndEmpty方法的結束而被關閉了,根本就和main方法沒有任何關係,因此main方法下面的輸出語句依然會輸出addressB所指向空間內的值。就是這麼簡單。spa

 

找到了問題天然要解決啊,可是我又不想經過return來返回,就是但願B這個map過一趟removeValueNullAndEmpty方法就把沒用的東西給丟掉了;怎麼辦呢?我首先是在原來的代碼上隨便作了點修改code

public static void removeValueNullAndEmpty(Map<String,String> A) {
        for(String key : A.keySet()){
            if(A.get(key) == null || "".equals(A.get(key))){
                A.remove(key);
            }
        }
    }

這樣固然不行了,一執行就報錯了blog

Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.HashMap$HashIterator.nextNode(Unknown Source)
    at java.util.HashMap$KeyIterator.next(Unknown Source)
    at test.Main.removeValueNullAndEmpty(Main.java:28)
    at test.Main.main(Main.java:52)

這一看就曉得了,keySet()拿出來的是個set視圖,這只是一個與map中鍵的映射;若是remove掉原map集合中的一個元素,就會影響到keySet()取到的set視圖的內容,進而影響到後續元素的獲取,因此這麼作是不被容許的,那麼只能想其餘辦法了。這時候,我想到了迭代器rem

public static void removeValueNullAndEmpty(Map<String,String> A) {
        Iterator<String> iterator = A.keySet().iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            if(A.get(key) == null || "".equals(A.get(key))){
                iterator.remove();
            }
            
        }
    }
    
    
    public static void main(String[] args) {
        Map<String,String> B = new HashMap<>();
        B.put("c", "3");
        B.put("d", "");
        B.put("e", null);
        removeValueNullAndEmpty(B);
        System.out.println(B);
        }

執行以後,就灰常正常了。get

{c=3}

ok,其實不是多大的問題,主要是對集合不熟悉的鍋就這樣吧it

相關文章
相關標籤/搜索