views:

96

answers:

2

I have the following code for sorting a ConcurrentHashMap:

ConcurrentHashMap<String,String> text = new ConcurrentHashMap<String,String>();
.... 
List<String> list = new ArrayList<String>(text.values());
Collections.sort(list);

Which throws a NoSuchElementException:

Caused by: java.util.NoSuchElementException
        at library.ArrayList$Itr.next(ArrayList.java:1232)
        at library.ArrayList$ListItr.next(ArrayList.java:1263)
        at java.util.Collections.sort(Collections.java:120)

And I can't work out why. Any ideas?

+1  A: 

According to the java api

NoSuchElementException Thrown by the nextElement method of an Enumeration to indicate that there are no more elements in the enumeration.

I tested the following code locally

ConcurrentHashMap<String, String> t = new ConcurrentHashMap<String, String>();

List<String> al = new ArrayList<String>(t.values());
Collections.sort(al);

System.out.println("no bugs");

(with Eclipse jdk 1.5) I get the expected output. I also ran my local test after putting some key-value pairs into the ConcurrentHashMap and had no problems. Based on my successes, it would seem that one (or both) of the following is causing the discrepancy between our results.

A) We are using different class implementations (I use java.util.concurrent.ConcurrentHashMap, java.util.List, java.util.ArrayList from jdk 1.5)

B) You are modifying the contents of ArrayList or ConcurrentHashMap WHILE an iterator is iterating through the contents of said object. Does the exception occur while running the sort? My best guess is another thread is messing with your ArrayList (since ConcurentHashMap is supposed to be thread safe) while you are sorting.

new Thrall
A: 

It's unnessary to create a new ArrayList for sorting,thus,you can do like this :

ConcurrentHashMap text = new ConcurrentHashMap(); List textList=text.values(); //unmodifiable List here. Collections.sort(textList);// it also can sort.

:EOF

Mercy