簡體   English   中英

從HashMap中刪除元素時發生異常java.util.ConcurrentModificationException

[英]Exception when removing element from HashMap java.util.ConcurrentModificationException

我正在嘗試編寫邏輯以找到最快的路線,輸入格式為“ 1-2-30#2-3-25#3-4-30#...”,這意味着從站點1到站點2需要30分鍾。 在此代碼中,當我遞歸調用searchMapKey()函數時,如果密鑰不存在,那么我將得到執行“線程“主”中的異常” java.util.ConcurrentModificationException”

    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.LinkedHashMap;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.Set;
    import java.util.StringTokenizer;

    public class QuickestRoute {
static int totalWeight = 0;

public static String outpit;

public static void main(String[] args) {
    // TODO Auto-generated method stub
    String input1[] = { "1-2-30#2-3-25#3-4-30#4-5-45#5-6-30#6-7-15#7-8-60#8-9-40",
            "10-11-45#11-4-60#4-12-60#12-13-45#13-14-30#14-15-35",
            "1-3-40#3-4-25#4-16-30#16-17-15#17-18-20#18-19-30#19-20-25", "21-12-30#12-17-180#17-22-45" }; };
    String input2 = "12#18";
    String[] output = quickestMetroRoute(input1, input2);
    /*
     * for(int i=0;i<output.length;i++) System.out.println(output[i]);
     */
}

public static String[] quickestMetroRoute(String[] input1, String input2) {
    // Write code here
    Map<String, Integer> input = new HashMap<String, Integer>();
    for (int i = 0; i < input1.length; i++) {
        StringTokenizer str = new StringTokenizer(input1[i], "#");
        while (str.hasMoreTokens()) {
            String[] parts = str.nextToken().split("-");
            String node = parts[0] + "-" + parts[1];
            int weight = Integer.parseInt(parts[2]);
            input.put(node, weight);
        }
    }
     Map<String, Integer> sortedMap = sortByValue(input);
    System.out.println(Collections.singletonList(sortedMap));
    String[] parts = input2.split("#");
    String source = parts[0];
    String destination = parts[1];
    searchMapKey(source, destination, sortedMap);
    /*
     * for (Map.Entry<String, Integer> entry : input.entrySet()) { String
     * key = entry.getKey(); Integer value = entry.getValue(); // ... }
     */
    System.out.println("outpit: " + outpit);
    System.out.println("totalWeight: " + totalWeight);

    return input1;
}

private static void searchMapKey(String source, String destination, Map<String, Integer> input) {
    // TODO Auto-generated method stub
    for (Iterator<Entry<String, Integer>> it = input.entrySet().iterator(); it.hasNext();) {
        Entry<String, Integer> entry = it.next();
        String key = entry.getKey();
        Integer value = entry.getValue();
        // ...
        String[] nodeParts = key.split("-");
        String nodeFirst = nodeParts[0];
        String nodeSecond = nodeParts[1];

        if (nodeFirst.equals(source)) {
            totalWeight += value;
            outpit += key;
            if (destination.equals(nodeSecond)) {
                totalWeight += value;
                outpit += key;
                return;
            } else {
                input.remove(key);
                searchMapKey(nodeSecond, destination, input);
            }
        }
        if (nodeSecond.equals(source)) {
            totalWeight += value;
            outpit += key;
            if (destination.equals(nodeFirst)) {
                totalWeight += value;
                outpit += key;
                return;
            } else {
                input.remove(key);
                searchMapKey(nodeFirst, destination, input);
            }
        }
    }

}

private static Map<String, Integer> sortByValue(Map<String, Integer> unsortMap) {

    // 1. Convert Map to List of Map
    List<Map.Entry<String, Integer>> list =
            new LinkedList<Map.Entry<String, Integer>>(unsortMap.entrySet());

    // 2. Sort list with Collections.sort(), provide a custom Comparator
    //    Try switch the o1 o2 position for a different order
    Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
        public int compare(Map.Entry<String, Integer> o1,
                           Map.Entry<String, Integer> o2) {
            return (o1.getValue()).compareTo(o2.getValue());
        }
    });

    // 3. Loop the sorted list and put it into a new insertion order Map LinkedHashMap
    Map<String, Integer> sortedMap = new LinkedHashMap<String, Integer>();
    for (Map.Entry<String, Integer> entry : list) {
        sortedMap.put(entry.getKey(), entry.getValue());
    }

    /*
    //classic iterator example
    for (Iterator<Map.Entry<String, Integer>> it = list.iterator(); it.hasNext(); ) {
        Map.Entry<String, Integer> entry = it.next();
        sortedMap.put(entry.getKey(), entry.getValue());
    }*/


    return sortedMap;
}

}

在具有活動Iterator修改Map會使迭代器無效。 如所見,根據地圖的確切內容,您可能會收到ConcurrentModificationException

解決此問題的一種方法是通過迭代器(即,調用it.remove() )進行修改,而不是直接在地圖上( input.remove(key) )進行修改。

試試這個代碼我做了2處修改

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.StringTokenizer;

public class QuickestRoute {
    static int totalWeight = 0;

    public static String outpit;

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String input1[] = { "1-2-30#2-3-25#3-4-30#4-5-45#5-6-30#6-7-15#7-8-60#8-9-40",
                "10-11-45#11-4-60#4-12-60#12-13-45#13-14-30#14-15-35",
                "1-3-40#3-4-25#4-16-30#16-17-15#17-18-20#18-19-30#19-20-25", "21-12-30#12-17-180#17-22-45" };

        String input2 = "12#18";
        String[] output = quickestMetroRoute(input1, input2);
        /*
         * for(int i=0;i<output.length;i++) System.out.println(output[i]);
         */
    }

    public static String[] quickestMetroRoute(String[] input1, String input2) {
        // Write code here
        Map<String, Integer> input = new HashMap<String, Integer>();
        for (int i = 0; i < input1.length; i++) {
            StringTokenizer str = new StringTokenizer(input1[i], "#");
            while (str.hasMoreTokens()) {
                String[] parts = str.nextToken().split("-");
                String node = parts[0] + "-" + parts[1];
                int weight = Integer.parseInt(parts[2]);
                input.put(node, weight);
            }
        }
        Map<String, Integer> sortedMap = sortByValue(input);
        System.out.println(Collections.singletonList(sortedMap));
        String[] parts = input2.split("#");
        String source = parts[0];
        String destination = parts[1];
        searchMapKey(source, destination, sortedMap);
        /*
         * for (Map.Entry<String, Integer> entry : input.entrySet()) { String
         * key = entry.getKey(); Integer value = entry.getValue(); // ... }
         */
        System.out.println("outpit: " + outpit);
        System.out.println("totalWeight: " + totalWeight);

        return input1;
    }

    private static void searchMapKey(String source, String destination, Map<String, Integer> input) {
        // TODO Auto-generated method stub

        ArrayList<Map<String, Integer>> removeList = new ArrayList<Map<String, Integer>>();
        for (Iterator<Entry<String, Integer>> it = input.entrySet().iterator(); it.hasNext();) {
            Entry<String, Integer> entry = it.next();
            String key = entry.getKey();
            Integer value = entry.getValue();
            // ...
            String[] nodeParts = key.split("-");
            String nodeFirst = nodeParts[0];
            String nodeSecond = nodeParts[1];

            if (nodeFirst.equals(source)) {
                totalWeight += value;
                outpit += key;
                if (destination.equals(nodeSecond)) {
                    totalWeight += value;
                    outpit += key;
                    return;
                } else {
                    it.remove();
                    // input.remove(key);
                    Map<String, Integer> next = new HashMap<String, Integer>();
                    next.putAll(input);
                    searchMapKey(nodeSecond, destination, next);
                }
            }
            if (nodeSecond.equals(source)) {
                totalWeight += value;
                outpit += key;
                if (destination.equals(nodeFirst)) {
                    totalWeight += value;
                    outpit += key;
                    return;
                } else {
                    it.remove();
                    // input.remove(key);
                    Map<String, Integer> next = new HashMap<String, Integer>();
                    next.putAll(input);
                    searchMapKey(nodeFirst, destination, next);
                }
            }
        }

    }

    private static Map<String, Integer> sortByValue(Map<String, Integer> unsortMap) {

        // 1. Convert Map to List of Map
        List<Map.Entry<String, Integer>> list = new LinkedList<Map.Entry<String, Integer>>(unsortMap.entrySet());

        // 2. Sort list with Collections.sort(), provide a custom Comparator
        // Try switch the o1 o2 position for a different order
        Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                return (o1.getValue()).compareTo(o2.getValue());
            }
        });

        // 3. Loop the sorted list and put it into a new insertion order Map
        // LinkedHashMap
        Map<String, Integer> sortedMap = new LinkedHashMap<String, Integer>();
        for (Map.Entry<String, Integer> entry : list) {
            sortedMap.put(entry.getKey(), entry.getValue());
        }

        /*
         * //classic iterator example for (Iterator<Map.Entry<String, Integer>>
         * it = list.iterator(); it.hasNext(); ) { Map.Entry<String, Integer>
         * entry = it.next(); sortedMap.put(entry.getKey(), entry.getValue()); }
         */

        return sortedMap;
    }

}

您的輸出

[{6-7=15, 16-17=15, 17-18=20, 19-20=25, 2-3=25, 3-4=25, 18-19=30, 13-14=30, 4-16=30, 1-2=30, 21-12=30, 5-6=30, 14-15=35, 8-9=40, 1-3=40, 10-11=45, 12-13=45, 17-22=45, 4-5=45, 7-8=60, 4-12=60, 11-4=60, 12-17=180}]
outpit: null21-1212-1313-1414-154-124-1616-1717-1817-1811-410-113-41-31-22-32-31-24-55-66-77-88-912-1717-1817-18
totalWeight: 975

您正在使用遞歸函數並在迭代器中刪除元素,並在與它們一起使用的另一個調用中再次刪除,我所做的是每次您刪除元素,對其進行復制然后將其轉發到進行中的遞歸調用中詢問是否不能清除

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM