如何在非线程方法中解决这个问题“线程中的exception”主“java.util.ConcurrentModificationException”
我试图从地图中删除值,当我尝试这个迭代时,我得到以下exception。
Exception in thread "main" java.util.ConcurrentModificationException
我的代码如下。
public static Map removeHolyday(Map daysMap,Map holydayMap){ Iterator
请帮我解决这个问题。
编辑:
这是我使用的代码,但该值不是从地图中删除的;
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){