如何在非线程方法中解决这个问题“线程中的异常”主“ java.util.ConcurrentModificationException" [英] how to solve this in non thread method "Exception in thread "main" java.util.ConcurrentModificationException"
问题描述
我试图从地图中删除值,当我尝试这个我得到以下异常时迭代。
I am trying to remove value from the map which is iterated when i try this i get the following exception .
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;
}
请帮我解决这个问题。
编辑:
这是我使用的代码,但是值不是从地图中删除gettig;
this is the code i use but the value is not gettig deleted from map;
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);
}
}
Regards
Antony
Regards Antony
推荐答案
在这种情况下,其实很简单 - 只需更改这一行:
In this case, it's actually pretty easy - just change this line:
daysMap.remove(workingDaysEntry.getKey().toString());
to:
workingDays.remove();
在迭代集合时,您可以仅进行更改通过迭代器的 remove()
方法,基本上。请注意,一些迭代器不支持删除 - 希望执行您使用的地图...
While you're iterating over a collection, you can only make changes to it via the iterator's remove()
method, basically. Note that some iterators don't support removal - hopefully the implementation of map you're using does...
编辑:我怀疑你有另一个错误,实际上。这行:
I suspect you've got another bug, actually. This line:
Iterator<Map.Entry> holydays = daysMap.entrySet().iterator();
应该是:
Iterator<Map.Entry> holydays = holydayMap.entrySet().iterator();
目前您甚至没有使用 holydayMap
。你也应该打电话给 remove()
- 你不能删除相同的条目两次。
At the moment you're not even using holydayMap
. You should also break after the call to remove()
- you can't remove the same entry twice.
编辑:我想我现在已经发现了这个问题,如果你使用泛型,你会发现自己。 holyDayMap
键都是字符串:
I think I've found the problem now, and you'd have found it yourself if you were using generics. The holyDayMap
keys are all strings:
Map holydaysMap = new ConcurrentHashMap();
holydaysMap.put("17","17-04-2012");
holydaysMap.put("25","25-04-2012");
...但工作日地图键是整数:
... but the working day map keys are integers:
for (int i = 1; i <= noofdays; i++) {
...
workingDaysMap.put(i,formatedDate);
}
现在17与17不一样,所以没有条目比赛。如果你用他们的键/值类型宣告你的地图,你会发现这一点。
Now "17" isn't the same as 17, so no entries will match. If you declared your maps with their key/value types, you'd spot this earlier.
请注意,你的工作代码示例 em>有这个问题 - 它使用字符串无处不在。
Note that your "working" code sample doesn't have this problem - it uses strings everywhere.
(你应该真的考虑字符串是否是正确的值用于开始 - 考虑使用 Joda时间和 LocalDate
用于日期表示...)
(You should really consider whether strings are the right values to use to start with - consider using Joda Time and LocalDate
for date representations...)
编辑:这是一个简短但完整的程序,显示 remove()
work:
Here's a short but complete program which shows remove()
working:
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}
所以你需要找出为什么你的代码不这样做。
So you need to work out why your code doesn't behave that way.
这篇关于如何在非线程方法中解决这个问题“线程中的异常”主“ java.util.ConcurrentModificationException"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!