[COLLECTIONS-237] Added MultiValueMap.iterator() and clarified javadoc for entrySet().
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/collections/trunk@1476553 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
50bd9f108b
commit
c9e1e5c8f5
|
@ -367,6 +367,12 @@
|
|||
<action issue="COLLECTIONS-240" dev="bayard" type="update" due-to="Wouter de Vaal">
|
||||
"MultiValueMap" is now serializable.
|
||||
</action>
|
||||
<action issue="COLLECTIONS-237" dev="tn" type="add" due-to="Nils Kaiser, Alan Mehlo">
|
||||
Added method "MultiValueMap#iterator()" to return a flattened version of
|
||||
"entrySet().iterator()". Clarified javadoc for "entrySet()" that the returned Entry
|
||||
objects are unflattened, i.e. the Entry object for a given key contains all values
|
||||
mapped to this key.
|
||||
</action>
|
||||
<action issue="COLLECTIONS-235" dev="bayard" type="add" due-to="Nathan Egge">
|
||||
Added method "ListUtils#indexOf(List, Predicate)".
|
||||
</action>
|
||||
|
|
|
@ -33,8 +33,11 @@ import org.apache.commons.collections4.CollectionUtils;
|
|||
import org.apache.commons.collections4.Factory;
|
||||
import org.apache.commons.collections4.FunctorException;
|
||||
import org.apache.commons.collections4.MultiMap;
|
||||
import org.apache.commons.collections4.Transformer;
|
||||
import org.apache.commons.collections4.iterators.EmptyIterator;
|
||||
import org.apache.commons.collections4.iterators.IteratorChain;
|
||||
import org.apache.commons.collections4.iterators.LazyIteratorChain;
|
||||
import org.apache.commons.collections4.iterators.TransformIterator;
|
||||
|
||||
/**
|
||||
* A MultiValueMap decorates another map, allowing it to have
|
||||
|
@ -195,7 +198,7 @@ public class MultiValueMap<K, V> extends AbstractMapDecorator<K, Object> impleme
|
|||
* Other values attached to that key are unaffected.
|
||||
* <p>
|
||||
* If the last value for a key is removed, <code>null</code> will be returned
|
||||
* from a subsequant <code>get(key)</code>.
|
||||
* from a subsequent <code>get(key)</code>.
|
||||
*
|
||||
* @param key the key to remove from
|
||||
* @param value the value to remove
|
||||
|
@ -293,6 +296,20 @@ public class MultiValueMap<K, V> extends AbstractMapDecorator<K, Object> impleme
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>
|
||||
* NOTE: the returned Entry objects will contain as value a {@link Collection}
|
||||
* of all values that are mapped to the given key. To get a "flattened" version
|
||||
* of all mappings contained in this map, use {@link #iterator()}.
|
||||
*
|
||||
* @see #iterator()
|
||||
*/
|
||||
@Override
|
||||
public Set<Entry<K, Object>> entrySet() {
|
||||
return super.entrySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a collection containing all the values in the map.
|
||||
* <p>
|
||||
|
@ -389,6 +406,48 @@ public class MultiValueMap<K, V> extends AbstractMapDecorator<K, Object> impleme
|
|||
return new ValuesIterator(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an iterator for all mappings stored in this {@link MultiValueMap}.
|
||||
* <p>
|
||||
* The iterator will return multiple Entry objects with the same key
|
||||
* if there are multiple values mapped to this key.
|
||||
* <p>
|
||||
* NOTE: calling {@link Map.Entry#setValue(Object)} on any of the returned
|
||||
* elements will result in a {@link UnsupportedOperationException}.
|
||||
*
|
||||
* @return the iterator of all mappings in this map
|
||||
* @since 4.0
|
||||
*/
|
||||
public Iterator<Entry<K, V>> iterator() {
|
||||
final Collection<K> allKeys = new ArrayList<K>(keySet());
|
||||
final Iterator<K> keyIterator = allKeys.iterator();
|
||||
|
||||
return new LazyIteratorChain<Entry<K, V>>() {
|
||||
protected Iterator<? extends Entry<K, V>> nextIterator(int count) {
|
||||
if ( ! keyIterator.hasNext() ) {
|
||||
return null;
|
||||
}
|
||||
final K key = keyIterator.next();
|
||||
final Transformer<V, Entry<K, V>> transformer = new Transformer<V, Entry<K, V>>() {
|
||||
public Entry<K, V> transform(final V input) {
|
||||
return new Entry<K, V>() {
|
||||
public K getKey() {
|
||||
return key;
|
||||
}
|
||||
public V getValue() {
|
||||
return input;
|
||||
}
|
||||
public V setValue(V value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
return new TransformIterator<V, Entry<K, V>>(new ValuesIterator(key), transformer);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the total size of the map by counting all the values.
|
||||
*
|
||||
|
|
|
@ -146,6 +146,30 @@ public class MultiValueMapTest<K, V> extends AbstractObjectTest {
|
|||
assertEquals(4, map.totalSize());
|
||||
}
|
||||
|
||||
public void testIterator() {
|
||||
final MultiValueMap<K, V> map = createTestMap();
|
||||
@SuppressWarnings("unchecked")
|
||||
Collection<V> values = new ArrayList<V>((Collection<V>) map.values());
|
||||
Iterator<Map.Entry<K, V>> iterator = map.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<K, V> entry = iterator.next();
|
||||
assertTrue(map.containsValue(entry.getKey(), entry.getValue()));
|
||||
assertTrue(values.contains(entry.getValue()));
|
||||
assertTrue(values.remove(entry.getValue()));
|
||||
}
|
||||
assertTrue(values.isEmpty());
|
||||
}
|
||||
|
||||
public void testRemoveAllViaEntryIterator() {
|
||||
final MultiValueMap<K, V> map = createTestMap();
|
||||
for (final Iterator<?> i = map.iterator(); i.hasNext();) {
|
||||
i.next();
|
||||
i.remove();
|
||||
}
|
||||
assertNull(map.get("one"));
|
||||
assertEquals(0, map.totalSize());
|
||||
}
|
||||
|
||||
public void testTotalSizeA() {
|
||||
assertEquals(6, createTestMap().totalSize());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue