You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by tn...@apache.org on 2013/04/27 13:08:27 UTC

svn commit: r1476553 - in /commons/proper/collections/trunk/src: changes/changes.xml main/java/org/apache/commons/collections4/map/MultiValueMap.java test/java/org/apache/commons/collections4/map/MultiValueMapTest.java

Author: tn
Date: Sat Apr 27 11:08:26 2013
New Revision: 1476553

URL: http://svn.apache.org/r1476553
Log:
[COLLECTIONS-237] Added MultiValueMap.iterator() and clarified javadoc for entrySet().

Modified:
    commons/proper/collections/trunk/src/changes/changes.xml
    commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/map/MultiValueMap.java
    commons/proper/collections/trunk/src/test/java/org/apache/commons/collections4/map/MultiValueMapTest.java

Modified: commons/proper/collections/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/changes/changes.xml?rev=1476553&r1=1476552&r2=1476553&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/changes/changes.xml (original)
+++ commons/proper/collections/trunk/src/changes/changes.xml Sat Apr 27 11:08:26 2013
@@ -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>

Modified: commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/map/MultiValueMap.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/map/MultiValueMap.java?rev=1476553&r1=1476552&r2=1476553&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/map/MultiValueMap.java (original)
+++ commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/map/MultiValueMap.java Sat Apr 27 11:08:26 2013
@@ -33,8 +33,11 @@ import org.apache.commons.collections4.C
 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
      * 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
@@ -294,6 +297,20 @@ public class MultiValueMap<K, V> extends
     }
 
     /**
+     * {@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>
      * This returns a collection containing the combination of values from all keys.
@@ -390,6 +407,48 @@ public class MultiValueMap<K, V> extends
     }
 
     /**
+     * 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.
      *
      * @return the total size of the map counting all values

Modified: commons/proper/collections/trunk/src/test/java/org/apache/commons/collections4/map/MultiValueMapTest.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/test/java/org/apache/commons/collections4/map/MultiValueMapTest.java?rev=1476553&r1=1476552&r2=1476553&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/test/java/org/apache/commons/collections4/map/MultiValueMapTest.java (original)
+++ commons/proper/collections/trunk/src/test/java/org/apache/commons/collections4/map/MultiValueMapTest.java Sat Apr 27 11:08:26 2013
@@ -146,6 +146,30 @@ public class MultiValueMapTest<K, V> ext
         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());
     }