diff --git a/RELEASE-NOTES.html b/RELEASE-NOTES.html index 1a85ceea5..716fef177 100644 --- a/RELEASE-NOTES.html +++ b/RELEASE-NOTES.html @@ -33,6 +33,7 @@ No interface changes, or deprecations have occurred.
  • MultiKey - Add getKey(index) and size() methods and make constructor public
  • AbstractHashedMap,AbstractLinkedMap - Add methods to access entry methods when protected scope blocks
  • Functors - Add get methods to retrieve internal state [27515]
  • +
  • MultiHashMap - Add five methods to improve the API
  • BUG FIXES

    diff --git a/src/java/org/apache/commons/collections/MultiHashMap.java b/src/java/org/apache/commons/collections/MultiHashMap.java index 1d831287d..94f8bcbf8 100644 --- a/src/java/org/apache/commons/collections/MultiHashMap.java +++ b/src/java/org/apache/commons/collections/MultiHashMap.java @@ -50,7 +50,7 @@ import java.util.Set; * list will be a list containing "A", "B", "C". * * @since Commons Collections 2.0 - * @version $Revision: 1.16 $ $Date: 2004/03/14 15:33:57 $ + * @version $Revision: 1.17 $ $Date: 2004/03/14 17:05:24 $ * * @author Christopher Berry * @author James Strachan @@ -130,6 +130,64 @@ public class MultiHashMap extends HashMap implements MultiMap { } //----------------------------------------------------------------------- + /** + * Gets the total size of the map by counting all the values. + * + * @return the total size of the map counting all values + * @since Commons Collections 3.1 + */ + public int totalSize() { + int total = 0; + Collection values = super.values(); + for (Iterator it = values.iterator(); it.hasNext();) { + Collection coll = (Collection) it.next(); + total += coll.size(); + } + return total; + } + + /** + * Gets the collection mapped to the specified key. + * This method is a convenience method to typecast the result of get(key). + * + * @param key the key to retrieve + * @return the collection mapped to the key, null if no mapping + * @since Commons Collections 3.1 + */ + public Collection getCollection(Object key) { + return (Collection) get(key); + } + + /** + * Gets the size of the collection mapped to the specified key. + * + * @param key the key to get size for + * @return the size of the collection at the key, zero if key not in map + * @since Commons Collections 3.1 + */ + public int size(Object key) { + Collection coll = getCollection(key); + if (coll == null) { + return 0; + } + return coll.size(); + } + + /** + * Gets an iterator for the collection mapped to the specified key. + * + * @param key the key to get an iterator for + * @return the iterator of the collection at the key, empty iterator if key not in map + * @since Commons Collections 3.1 + */ + public Iterator iterator(Object key) { + Collection coll = getCollection(key); + if (coll == null) { + return IteratorUtils.EMPTY_ITERATOR; + } + return coll.iterator(); + } + /** * Adds the value to the collection associated with the specified key. *

    @@ -143,16 +201,40 @@ public class MultiHashMap extends HashMap implements MultiMap { public Object put(Object key, Object value) { // NOTE:: put is called during deserialization in JDK < 1.4 !!!!!! // so we must have a readObject() - Collection coll = (Collection) super.get(key); + Collection coll = getCollection(key); if (coll == null) { coll = createCollection(null); super.put(key, coll); } boolean results = coll.add(value); - return (results ? value : null); } + /** + * Adds a collection of values to the collection associated with the specified key. + * + * @param key the key to store against + * @param values the values to add to the collection at the key, null ignored + * @return true if this map changed + * @since Commons Collections 3.1 + */ + public boolean putAll(Object key, Collection values) { + if (values == null || values.size() == 0) { + return false; + } + Collection coll = getCollection(key); + if (coll == null) { + coll = createCollection(values); + if (coll.size() == 0) { + return false; + } + super.put(key, coll); + return true; + } else { + return coll.addAll(values); + } + } + /** * Checks whether the map contains the value specified. *

    @@ -178,6 +260,21 @@ public class MultiHashMap extends HashMap implements MultiMap { return false; } + /** + * Checks whether the collection at the specified key contains the value. + * + * @param value the value to search for + * @return true if the map contains the value + * @since Commons Collections 3.1 + */ + public boolean containsValue(Object key, Object value) { + Collection coll = getCollection(key); + if (coll == null) { + return false; + } + return coll.contains(value); + } + /** * Removes a specific value from map. *

    @@ -192,7 +289,7 @@ public class MultiHashMap extends HashMap implements MultiMap { * @return the value removed (which was passed in), null if nothing removed */ public Object remove(Object key, Object item) { - Collection valuesForKey = (Collection) super.get(key); + Collection valuesForKey = getCollection(key); if (valuesForKey == null) { return null; } diff --git a/src/test/org/apache/commons/collections/TestMultiHashMap.java b/src/test/org/apache/commons/collections/TestMultiHashMap.java index 5345c06eb..b77be9183 100644 --- a/src/test/org/apache/commons/collections/TestMultiHashMap.java +++ b/src/test/org/apache/commons/collections/TestMultiHashMap.java @@ -15,6 +15,8 @@ */ package org.apache.commons.collections; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.Map; @@ -27,7 +29,7 @@ import org.apache.commons.collections.map.AbstractTestMap; /** * Unit Tests for MultiHashMap. * - * @version $Revision: 1.17 $ $Date: 2004/02/18 01:20:35 $ + * @version $Revision: 1.18 $ $Date: 2004/03/14 17:05:24 $ * * @author Unknown */ @@ -244,4 +246,103 @@ public class TestMultiHashMap extends AbstractTestMap { values = map.values(); super.verifyValues(); } + + //----------------------------------------------------------------------- + public void testGetCollection() { + MultiHashMap map = new MultiHashMap(); + map.put("A", "AA"); + assertSame(map.get("A"), map.getCollection("A")); + } + + public void testTotalSize() { + MultiHashMap map = new MultiHashMap(); + assertEquals(0, map.totalSize()); + map.put("A", "AA"); + assertEquals(1, map.totalSize()); + map.put("B", "BA"); + assertEquals(2, map.totalSize()); + map.put("B", "BB"); + assertEquals(3, map.totalSize()); + map.put("B", "BC"); + assertEquals(4, map.totalSize()); + map.remove("A"); + assertEquals(3, map.totalSize()); + map.remove("B", "BC"); + assertEquals(2, map.totalSize()); + } + + public void testSize_Key() { + MultiHashMap map = new MultiHashMap(); + assertEquals(0, map.size("A")); + assertEquals(0, map.size("B")); + map.put("A", "AA"); + assertEquals(1, map.size("A")); + assertEquals(0, map.size("B")); + map.put("B", "BA"); + assertEquals(1, map.size("A")); + assertEquals(1, map.size("B")); + map.put("B", "BB"); + assertEquals(1, map.size("A")); + assertEquals(2, map.size("B")); + map.put("B", "BC"); + assertEquals(1, map.size("A")); + assertEquals(3, map.size("B")); + map.remove("A"); + assertEquals(0, map.size("A")); + assertEquals(3, map.size("B")); + map.remove("B", "BC"); + assertEquals(0, map.size("A")); + assertEquals(2, map.size("B")); + } + + public void testIterator_Key() { + MultiHashMap map = new MultiHashMap(); + assertEquals(false, map.iterator("A").hasNext()); + map.put("A", "AA"); + Iterator it = map.iterator("A"); + assertEquals(true, it.hasNext()); + it.next(); + assertEquals(false, it.hasNext()); + } + + public void testContainsValue_Key() { + MultiHashMap map = new MultiHashMap(); + assertEquals(false, map.containsValue("A", "AA")); + assertEquals(false, map.containsValue("B", "BB")); + map.put("A", "AA"); + assertEquals(true, map.containsValue("A", "AA")); + assertEquals(false, map.containsValue("A", "AB")); + } + + public void testPutAll_KeyCollection() { + MultiHashMap map = new MultiHashMap(); + Collection coll = Arrays.asList(new Object[] {"X", "Y", "Z"}); + + assertEquals(true, map.putAll("A", coll)); + assertEquals(3, map.size("A")); + assertEquals(true, map.containsValue("A", "X")); + assertEquals(true, map.containsValue("A", "Y")); + assertEquals(true, map.containsValue("A", "Z")); + + assertEquals(false, map.putAll("A", null)); + assertEquals(3, map.size("A")); + assertEquals(true, map.containsValue("A", "X")); + assertEquals(true, map.containsValue("A", "Y")); + assertEquals(true, map.containsValue("A", "Z")); + + assertEquals(false, map.putAll("A", new ArrayList())); + assertEquals(3, map.size("A")); + assertEquals(true, map.containsValue("A", "X")); + assertEquals(true, map.containsValue("A", "Y")); + assertEquals(true, map.containsValue("A", "Z")); + + coll = Arrays.asList(new Object[] {"M"}); + assertEquals(true, map.putAll("A", coll)); + assertEquals(4, map.size("A")); + assertEquals(true, map.containsValue("A", "X")); + assertEquals(true, map.containsValue("A", "Y")); + assertEquals(true, map.containsValue("A", "Z")); + assertEquals(true, map.containsValue("A", "M")); + } + }