Reputation: 17806
I'm trying to split a list of records into sublists of records. I successfully split the list into sublists, I wanted to see the contents of the sublists, but somehow I keep running into this ConcurrentModificationException.
My split method:
/**
* @param list - list of results
* @param size - how many sublists
* @return ret - returns a list containing the sublists
* */
public static <T> List<List<T>> split(List<T> list, int size) throws NullPointerException, IllegalArgumentException {
if (list == null) {
throw new NullPointerException("The list parameter is null.");
}
if (size <= 0) {
throw new IllegalArgumentException("The size parameter must be more than 0.");
}
int recordsPerSubList = list.size() / size; // how many records per sublist
List<List<T>> sublists = new ArrayList<List<T>>(size); // init capacity of sublists
// add the records to each sublist
for (int i=0; i<size; i++) {
sublists.add(i, list.subList(i * recordsPerSubList, (i + 1) * recordsPerSubList));
}
// for the remainder records, just add them to the last sublist
int mod = list.size() % recordsPerSubList;
if (mod > 0) {
int remainderIndex = list.size() - mod;
sublists.get(size - 1).addAll(list.subList(remainderIndex, list.size()));
}
return sublists;
}
I call it here:
List<List<QuoteSearchInfo>> ret = Util.split(quoteSearchInfoList, 5);
int fileCounter = 0;
for (List<QuoteSearchInfo> sublist : ret) {
fileCounter++;
String sublistJson = new Gson().toJson(sublist);
filename = JSON_FILE_NAME + fileCounter + JSON_FILE_END;
saveToFile(filename, sublistJson);
AWSManager.getInstance().uploadQuoteSearchJson(filename);
}
^ Here I am trying to split the list into sublists so I can upload them to S3.
and the stack trace:
java.util.ConcurrentModificationException
at java.util.SubList.checkForComodification(AbstractList.java:752)
at java.util.SubList.listIterator(AbstractList.java:682)
at java.util.AbstractList.listIterator(AbstractList.java:284)
at java.util.SubList.iterator(AbstractList.java:678)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:95)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:60)
at com.google.gson.Gson.toJson(Gson.java:546)
at com.google.gson.Gson.toJson(Gson.java:525)
at com.google.gson.Gson.toJson(Gson.java:480)
at com.google.gson.Gson.toJson(Gson.java:460)
at com.crover.QuoteSearchRover.execute(QuoteSearchRover.java:41)
at com.crover.CroverMain.execute(CroverMain.java:85)
at com.crover.CroverMain.main(CroverMain.java:35)
Upvotes: 2
Views: 1733
Reputation: 198023
sublists.get(size - 1).addAll(list.subList(remainderIndex, list.size()));
sublists.get(size - 1)
is a live view of a subrange of the list, so when you add elements to it, you're adding elements to the original list as well, at the same time that you're trying to get elements out from list.subList
. In general, you can't modify a list while you're iterating over it.
The simplest solution is not to add the elements to sublists.get(size - 1)
, but just to update it:
sublists.set(size - 1,
list.subList(remainderIndex - recordsPerSublist, list.size()));
Upvotes: 6