Don't allow MapCollections to iterate past the end.

Prior to this CL, MapCollections such as ArrayMap's entrySet,
keySet and values, exhibited unusual Iterator behavior:
 - instead of throwing NoSuchElementException once the end of
   the Collection was reached, Iterator.next() instead returned
   a null key / a null value / an entry with a null key and value.
 - however, remove() removed the last actual element of the
   Collection; successive calls of next(), remove() would
   result in successive elements being removed, in reverse
   iteration order.
 - Once the Collection had been cleared through calls to remove(),
   ArrayIndexOutOfBoundsException was thrown from iterator.next()
   (for keySet and values) or from iterator.remove (for entrySet).

This CL fixes those Collections' Iterators to let next() throw
NoSuchElementException when hasNext() would have returned false.
Since the new behavior was already guaranteed by the Iterator
documentation, any app compatibility effect from this CL is both
unlikely, and unlikely to be negative.

Bug: 19853326
Test: make cts && cts-tradefed run cts -m CtsUtilTestCases
Change-Id: Ie3f0594f434dd5625799791829bd94fbaef94906
This commit is contained in:
Tobias Thierer
2017-02-07 23:58:17 +00:00
parent c7eefdbda7
commit 093572cd1b

View File

@@ -22,6 +22,7 @@ import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
/**
@@ -52,6 +53,7 @@ abstract class MapCollections<K, V> {
@Override
public T next() {
if (!hasNext()) throw new NoSuchElementException();
Object res = colGetEntry(mIndex, mOffset);
mIndex++;
mCanRemove = true;
@@ -87,6 +89,7 @@ abstract class MapCollections<K, V> {
@Override
public Map.Entry<K, V> next() {
if (!hasNext()) throw new NoSuchElementException();
mIndex++;
mEntryValid = true;
return this;