I was looking over Java's ConcurrentSkipListMap, because it's an fascinating data structure and seem applicable to my use, but the iterator has some interesting behavior that seems counterintuitive to me. Take for example the following code:
Map<String, Integer> ages = new ConcurrentSkipListMap<>();
ages.put("Bob", 28);
Iterator<Entry<String, Integer>> iterator = ages.entrySet().iterator();
System.out.println("HasBob? " + iterator.hasNext());
iterator.next();
ages.put("Jon", 25);
System.out.println("HasJon? " + iterator.hasNext());
The idea is that the map is initialized with values, create an iterator, and starts iterating. In between these operations, another thread puts 'Jon' in the map. For simplicity's sake, instead of using actual threads and loops in my example, I just put the code in the contrived order, and directly reference each item.
I expected the output to be true/true
, but the actual output is true/false
. Digging into the Map's implementation, I found the iterator caches the next Node/Value (in its advance() method). This cache will skip any next items created right after iterator.next() is called. Why does it greedily cache the next item instead of waiting until the Iterator next() method is called before advancing the next item?