如何在非线程方法中解决这个问题“线程中的exception”主“java.util.ConcurrentModificationException”

我试图从地图中删除值,当我尝试这个迭代时,我得到以下exception。

Exception in thread "main" java.util.ConcurrentModificationException 

我的代码如下。

 public static Map removeHolyday(Map daysMap,Map holydayMap){ Iterator workingDays = daysMap.entrySet().iterator(); while (workingDays.hasNext()) { Map.Entry workingDaysEntry = workingDays.next(); System.out.println("Key = " + workingDaysEntry.getKey() + ", Value = " + workingDaysEntry.getValue()); Iterator 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 holyDayiterator = holydayMap.entrySet().iterator(); while (holyDayiterator.hasNext()) { Map.Entry holyDayEntry = holyDayiterator.next(); Iterator 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 holyDayiterator = holydayMap.entrySet().iterator(); while (holyDayiterator.hasNext()) { Map.Entry holyDayEntry = holyDayiterator.next(); Iterator 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); } } 

关心安东尼

在这种情况下,它实际上非常简单 – 只需更改此行:

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

至:

 workingDays.remove(); 

当你在一个集合上进行迭代时,你只能通过迭代器的remove()方法对它进行更改。 请注意,某些迭代器不支持删除 – 希望您正在使用的地图的实现确实…

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

 Iterator holydays = daysMap.entrySet().iterator(); 

应该是:

 Iterator holydays = holydayMap.entrySet().iterator(); 

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

编辑:我想我现在已经发现了问题,如果你使用generics,你会自己找到它。 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 Time和LocalDate进行日期表示......)

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

 import java.util.*; public class Test { public static void main(String[] args) { Map map = new HashMap(); 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 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} 

因此,您需要弄清楚为什么您的代码不会以这种方式运行。

将第一个映射(daysMap)构造为ConcurrentHashMap ,并将方法签名更改为:

 public static Map removeHolyday(ConcurrentHashMap daysMap,Map holydayMap){