RFR(s): 8072726: add adapter to convert Enumeration to Iterator

Stuart Marks stuart.marks at oracle.com
Tue May 19 21:08:32 UTC 2015

On 5/19/15 3:07 AM, Paul Sandoz wrote:
> Since this method transfers control it seems a little mean to place such a restriction on the returned Iterator. Although, there is no clear means of stating to the caller whether such an iterator supports removal or not, but that seems to be generally the case for any Iterator returning method.

On 19 May 2015, at 17:13, Daniel Fuchs <daniel.fuchs at oracle.com> wrote:
> What should ConcurrentHashMap.keys().asIterator().remove() do?

On 5/19/15 9:19 AM, Chris Hegarty wrote:
> +     * @implSpec
> +     * The returned Iterator's {@link Iterator#hasNext hasNext} method calls and returns
> +     * the value from this Enumeration's {@code hasMoreElements} method; its
> +     * {@link Iterator#next next} method calls and returns the value from this Enumeration's
> +     * {@code nextElement} method; and its {@link Iterator#remove remove} method throws
> +     * {@code UnsupportedOperationException}.
> Why not turn the proposed implSpec into an implNote, and leave it up to other API’s returning Enumerations to specify their behaviour of asIterator, if they override the default.

Wait. The interface *contract* part of the spec doesn't place any restrictions 
on the remove() method of the returned Iterator. It's silent about remove(), and 
indeed Iterator.remove() is already optional, so you have to look for the spec 
of the actual Iterator implementation to find out what it does.

It's the @implSpec section that says that it throws 
UnsupportedOperationException. That's necessary because Enumeration.asIterator() 
is a default method, so its implementation must be specified so that subclassers 
can decide whether to override. (See [1] for further information.)

With the proposed changeset,


will throw UnsupportedOperationException since it doesn't override remove(). Now 
CHM uses the same object to implement both Iterator and Enumeration, so 
presumably it could override asIterator() to return "this" and thereby support 
the remove() operation.

However, I don't think there's any point to doing this, as there are already 
better ways to iterate a CHM.

Specifying the behavior of an implementation that doesn't have a public class 
has always been a bit problematic. See CHM.keySet()'s discussion of 
Iterator.remove(). Anything that overrides Enumeration.asIterator().remove() to 
do something other than the default would have to do something similar.


[1] https://bugs.openjdk.java.net/browse/JDK-8068562

More information about the core-libs-dev mailing list