Skip to content

JDOM2 Feature Collections

paulk-asert edited this page Apr 9, 2012 · 4 revisions

All JDOM class instances that have core Java API interfaces (List, Iterator, ListIterator, etc.) now behave in the exact same way as those core API implementations. JDOM classes throw NullPointerException, ConcurrentModificationException, ClassCastException, NoSuchElementException, IllegalStateException, etc. in the same circumstances that the core API implementations would. This provides a measure of consistency and predictability.

The core JDOM Lists and Iterators have been streamlined and profiled to make them more efficient. Navigating JDOM is more efficient. One significant change in this regard is that the Filtered Content Lists in Element and Document now have a lazy-initialization process. Specifically, in JDOM 1.x, all Filtered Lists and Iterators would immediately scan and index the underlying List. In JDOM2 this process is done only as-needed.

In addition, all the Iterator modification methods are now fully supported. You can use the remove() method on simple Iterators, and the add(), remove(), set() methods on ListIterator instances. This includes the now more efficient DescendantIterator that is available using the getDescendants() or getDescendants(Filter) on Element or Document.

Obviously this excludes some collections which are read-only, like the results of XPath expressions, and the getNamespacesInScope() collections. Those Collections and Interators will throw UnsupportedOperationException if attempts are made to modify them.

A special mention should be made of getDescendants() and getDescendants(Filter). These methods returned a 'simple' Iterator in JDOM 1.x. In JDOM 2.x these methods return a new type which extends Iterator called IteratorIterable. This new interface represents both an Iterator, and an Iterable. It is thus possible to treat getDescendants(*) as either an Iterator (like JDOM 1.x), or as input in an enhanced-for loop introduced in Java 5:

for (Element e : doc.getDescendants(Filters.element())) {
   .... // do something with Elements....
}

There is one significant deviation from JDOM 1.x with respect to some Collections. The Element and Document Content has been stored in a List in JDOM, and this list has always thrown a ConcurrentModificationException if a particular Content item in the List has been 'swapped' with a List.set() call (or the set() call of some other Iterator). This does not conform to the java.util.* general implementations of List because set() is not considered to be a 'structural modification' to the list (it does not change the List's size). JDOM2 replicates the behaviour of other List implementations, and the set() method call on the List of Content no longer triggers a ConcurrentModificationException in active Iterators.

Clone this wiki locally