-1

我试图从映射中删除值,当我尝试这个时,我得到以下异常。

Exception in thread "main" java.util.ConcurrentModificationException

我的代码如下。

public static Map removeHolyday(Map daysMap,Map holydayMap){
        Iterator<Map.Entry> workingDays = daysMap.entrySet().iterator();
          while (workingDays.hasNext()) {
              Map.Entry workingDaysEntry = workingDays.next();
              System.out.println("Key = " + workingDaysEntry.getKey() + ", Value = " + workingDaysEntry.getValue());
              Iterator<Map.Entry> holydays = daysMap.entrySet().iterator();
              while (holydays.hasNext()) {
                  Map.Entry holydayEntry = holydays.next();
                  if(workingDaysEntry.getKey().toString().equals(holydayEntry.getKey().toString())){
                      daysMap.remove(workingDaysEntry.getKey().toString());
                  }
              }
          }
        return daysMap;
    }

请帮我解决这个问题。

编辑 :

这是我使用的代码,但该值并未从地图中删除;

package sample;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

class Workindays {
    public static int findNoOfDays(int year, int month, int day) {
        Calendar calendar = Calendar.getInstance();
        System.out.println("month : " + month);
        calendar.set(year, month - 1, day);
        int days = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        System.out.println("days :"+days);
        return days;
    }
    public static Map getHolydaysMap(int year, int month, int day) {
        //connect with database and check whether the date is holyday query is = SELECT * FROM holiday_calendar h WHERE date >='2008-10-01' AND date <='2008-10-30' AND type='Fixed';
        Map holydaysMap = new ConcurrentHashMap(); 
        holydaysMap.put("17","17-04-2012");
        holydaysMap.put("25","25-04-2012");
        return holydaysMap;
    }
    public static Map getWorkingDaysMap(int year, int month, int day){
        int totalworkingdays=0,noofdays=0;
        String nameofday = "";
        Map workingDaysMap = new HashMap();
        Map holyDayMap = new ConcurrentHashMap();
        noofdays = findNoOfDays(year,month,day);
        holyDayMap = getHolydaysMap(year,month,day);

        for (int i = 1; i <= noofdays; i++) {
            Date date = (new GregorianCalendar(year,month - 1, i)).getTime(); // year,month,day
            SimpleDateFormat f = new SimpleDateFormat("EEEE");
            nameofday = f.format(date);
            String formatedDate = i + "-" + month + "-" + year;
            if(!(nameofday.equals("Saturday") || nameofday.equals("Sunday"))){
                workingDaysMap.put(i,formatedDate);
                totalworkingdays++;
            }
        }
        workingDaysMap.put("totalworkingdays", totalworkingdays);
        System.out.println("removeHolyday : "+removeHolyday(workingDaysMap,holyDayMap));
        return workingDaysMap;
    }

    public static Map removeHolyday(Map daysMap,Map holydayMap){
        Iterator<Map.Entry> holyDayiterator = holydayMap.entrySet().iterator();
          while (holyDayiterator.hasNext()) {
              Map.Entry holyDayEntry = holyDayiterator.next();
             Iterator<Map.Entry> daysiterator = daysMap.entrySet().iterator();

             while (daysiterator.hasNext()) {
                  Map.Entry daysEntry = daysiterator.next();
                  if(daysEntry.getKey().equals(holyDayEntry.getKey()))
                      daysMap.remove(holyDayEntry.getKey());
              }
          }
System.out.println(daysMap);
        return daysMap;
    }

    public static void main(String[] args) {
        String delimiter = null, dateValues[] = null, startDate = "01-04-2012";
        int year = 0,month=0,day=0,totalworkingdays = 0;
        Map workingDaysMap = new LinkedHashMap();

        startDate = "01-04-2012";
        delimiter = "-";
        dateValues = startDate.split(delimiter);

        year = Integer.parseInt(dateValues[2]);
        month = Integer.parseInt(dateValues[1]);
        day = Integer.parseInt(dateValues[0]);

        workingDaysMap = getWorkingDaysMap(year, month, day);
        System.out.println("workingdays map : "+workingDaysMap);

    }
}

工作代码:

package sample;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class Main {
    public static Map removeHolyday(Map daysMap,Map holydayMap){
        Iterator<Map.Entry> holyDayiterator = holydayMap.entrySet().iterator();
          while (holyDayiterator.hasNext()) {
              Map.Entry holyDayEntry = holyDayiterator.next();
             Iterator<Map.Entry> daysiterator = daysMap.entrySet().iterator();

             while (daysiterator.hasNext()) {
                  Map.Entry daysEntry = daysiterator.next();
                  if(daysEntry.getKey().equals(holyDayEntry.getKey()))
                      daysMap.remove(holyDayEntry.getKey());
              }
          }
System.out.println(daysMap);
        return daysMap;
    }
    public static void main(String[] args) {

        Map holydaysMap = new ConcurrentHashMap(); 
        holydaysMap.put("17", "17-04-2012");
        holydaysMap.put("25", "25-04-2012");

    Map holydayMap = new HashMap(); 
    holydayMap.put("17", "17-04-2012");
    holydayMap.put("25", "25-04-2012");
    holydayMap.put("3", "03-04-2012");
    holydayMap.put("4", "04-04-2012");

    removeHolyday(holydayMap, holydaysMap);

}
}

问候安东尼

4

2 回答 2

2

在这种情况下,它实际上很容易 - 只需更改此行:

daysMap.remove(workingDaysEntry.getKey().toString());

至:

workingDays.remove();

在迭代集合时,基本上只能通过迭代器的方法对其进行更改。remove()请注意,某些迭代器不支持删除 - 希望您正在使用的 map 的实现确实......

编辑:我怀疑你有另一个错误,实际上。这一行:

Iterator<Map.Entry> holydays = daysMap.entrySet().iterator();

应该是:

Iterator<Map.Entry> holydays = holydayMap.entrySet().iterator();

目前你甚至没有使用holydayMap. 您还应该在调用后中断remove()- 您不能两次删除相同的条目。

编辑:我想我现在已经找到了问题,如果您使用泛型,您会自己发现问题。holyDayMap键都是字符串:

Map holydaysMap = new ConcurrentHashMap(); 
holydaysMap.put("17","17-04-2012");
holydaysMap.put("25","25-04-2012");

...但工作日地图键是整数:

    for (int i = 1; i <= noofdays; i++) {
        ...
        workingDaysMap.put(i,formatedDate);
    }

现在“17”与 17 不同,因此不会匹配任何条目。如果你用它们的键/值类型声明你的地图,你会更早发现这一点。

请注意,您的“工作”代码示例没有这个问题 - 它在任何地方都使用字符串。

(您应该真正考虑字符串是否是开始使用的正确值 - 考虑使用Joda TimeLocalDate日期表示......)

编辑:这是一个简短但完整的程序,显示remove()工作:

import java.util.*;

public class Test {
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<String, String>();
        map.put("foo1", "a");
        map.put("foo2", "b");
        map.put("bar1", "c");
        map.put("bar2", "d");
        map.put("foo3", "e");
        System.out.println("Before: " + map);

        Iterator<String> iterator = map.keySet().iterator();
        while (iterator.hasNext()) {
            if (iterator.next().startsWith("foo")) {
                iterator.remove();
            }
        }
        System.out.println("After: " + map);
    }
}

输出:

Before: {foo3=e, foo2=b, foo1=a, bar1=c, bar2=d}
After: {bar1=c, bar2=d}

所以你需要弄清楚为什么你的代码不这样。

于 2012-05-22T08:15:52.467 回答
1

构造第一个 map(daysMap)ConcurrentHashMap并将您的方法签名更改为:

public static Map removeHolyday(ConcurrentHashMap daysMap,Map holydayMap){
于 2012-05-22T09:31:08.997 回答