A behavior mismatch in AbstractCollection.toArray(T[] )

David Holmes david.holmes at oracle.com
Wed Dec 14 05:01:54 UTC 2011

Sean, Ulf,

I retract all my previous comments - they were completely wrong. 
AbstractCollection.toArray _does_ address concurrent modification:

"This implementation returns an array containing all the elements 
returned by this collection's iterator in the same order, stored in 
consecutive elements of the array, starting with index 0. If the number 
of elements returned by the iterator is too large to fit into the 
specified array, then the elements are returned in a newly allocated 
array with length equal to the number of elements returned by the 
iterator, even if the size of this collection changes during iteration, 
as might happen if the collection permits concurrent modification during 
iteration. The size method is called only as an optimization hint; the 
correct result is returned even if the iterator returns a different 
number of elements. "

As the number of elements to be returned by the iterator can not be 
known until iteration completes, it follows that only then can the 
question of whether or not the specified array is large enough, be 
answered. Consequently if the number of elements returned by the 
iterator would fit in the specified array then the specified array must 
be returned. So I would say that this is a bug in the JDK's 
AbstractCollection implementation afterall.

Note that the above part of the "spec" is an "implementation note" that 
describes the JDKs implementation of AbstractCollection - it is not part 
of the specification for AbstractCollection such that a third party 
implementor would have to do the same. Further, the use of 
AbstractCollection as a base implementation for the Set returned by 
ConcurrentHashMap.values() is part of the internal implementation 
details of CHM, not part of the spec for CHM.values().

So although this is a bug in the JDKs implementation of 
AbstractCollection, based on its own implementation note, it is not 
behaviour that a portable application should rely on.

My apologies for my confusion on this issue.


On 14/12/2011 12:42 PM, Sean Chou wrote:
>   Yeah, that is the reason I think a declaimer about "not designed for
> concurrent
> operation. " in the spec would be a proper choice.
> On Tue, Dec 13, 2011 at 10:20 PM, Ulf Zibis <Ulf.Zibis at gmx.de
> <mailto:Ulf.Zibis at gmx.de>> wrote:
>     IMO in 99.8 % this check would be superfluous overhead.
>     For those, who want 100 %, they can check and copy in their code.
>     -Ulf
>     Am 13.12.2011 14:30, schrieb Sean Chou:
>         Sorry for the confuse. By "ok", I mean "compare the size of
>         array which is
>         going to be
>         returned and the size of the specified array, and copy the elements
>         into the specified
>         array if it is larger and return the specified array."
>         Nothing is causing problem for now, I just found a mismatch. I
>         think most
>         guys will
>         just use the returned array without checking if it's the
>         specified one; and
>         this is also
>         why I think it may be possible to modify the behavior without
>         causing
>         problems.
>         And I think modifying ConcurrentHashMap is as dangerous as modifying
>         AbstractCollection
>         if people are relying on implementation, is this right? So it
>         seems we can
>         do nothing
>         to the mismatch now...
> --
> Best Regards,
> Sean Chou

More information about the core-libs-dev mailing list