2

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)
5
  • post the exception stack trace. Commented May 17, 2013 at 21:30
  • @Pangea added, it looks like something went wrong when i was trying to gson the list. Commented May 17, 2013 at 21:33
  • This exception normally means that the list is modified while being iterated over. What does GSON do under the hood? Also you might want to change the company name to something different. Commented May 17, 2013 at 21:35
  • @ZiyaoWei company name? Commented May 17, 2013 at 21:37
  • @ZiyaoWei haha, thanks! did not catch that. Commented May 17, 2013 at 21:38

1 Answer 1

6
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()));
Sign up to request clarification or add additional context in comments.

2 Comments

currently in my code i would have 5 lists, where the first 4 lists would have equal lengths. the last(5th) list would contain the length whatever other lists has PLUS any remainder records. wouldn't that code replace what the 5th list is?
This looks like the answer, but the stacktrace says the exception does not happen in the split method; any comments?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.