You need to store multiple
values for a single key in a
Map
. Instead of a one-to-one relationship between
keys and values, you need a Map
that provides
one-to-many relationships between keys and values.
Use a MultiMap
. A
MultiMap
maintains a collection of values for a given key. When a new
key/value pair is added to a MultiMap
, the value
is added to the collection of values for that key. The
MultiMap
also provides a way to remove a specific
key/value pair. The following example demonstrates the use of
MultiMap
:
import org.apache.commons.collections.MultiMap; import org.apache.commons.collections.MultiHashMap; MultiMap map = new MultiHashMap( ); map.put( "ONE", "TEST" ); map.put( "TWO", "PICNIC" ); map.put( "ONE", "HELLO" ); map.put( "TWO", "TESTIMONY" ); Set keySet = map.keySet( ); Iterator keyIterator = keySet.iterator( ); while( keyIterator.hasNext( ) ) { Object key = keyIterator.next( ); System.out.print( "Key: " + key + ", " ); Collection values = (Collection) map.get( key ); Iterator valuesIterator = values.iterator( ); while( valuesIterator.hasNext( ) ) { System.out.print( "Value: " + valuesIterator.next( ) + ". " ); } System.out.print( " " ); }
Each key in a MultiMap
corresponds to a collection
of values. This example produces the following output while iterating
through all values for each key:
Key: ONE, Value: TEST. Value: HELLO Key: TWO, Value: PICNIC. Value: Testimony
In a traditional Map
, a key is removed with
map.remove( )
; this method removes the specified key from
the map. In a MultiMap
, a specific key/value pair
can be removed from a key’s value collection. When
removing a specific pair, the value is extracted from a
key’s value collection. Example 5-10
demonstrates the use of a MultiMap.remove()
method.
Example 5-10. Using MultiMap.remove( )
package com.discursive.jccook.collections.map; import org.apache.commons.collections.*; import java.util.*; public class MultiMapExample { public static void main(String[] args) { MultiMapExample example = new MultiMapExample( ); example.start( ); } public void start( ) { MultiMap map = new MultiHashMap( ); map.put( "ONE", "TEST" ); map.put( "ONE", "WAR" ); map.put( "ONE", "CAR" ); map.put( "ONE", "WEST" ); map.put( "TWO", "SKY" ); map.put( "TWO", "WEST" ); map.put( "TWO", "SCHOOL" ); // At this point "ONE" should correspond to "TEST", "WAR", "CAR", "WEST" map.remove( "ONE", "WAR" ); map.remove( "ONE", "CAR" ); // The size of this collection should be two "TEST", "WEST" Collection oneCollection = (Collection) map.get("ONE"); // This collection should be "TEST", "WEST", "SKY", "WEST", "SCHOOL" Collection values = map.values( ); } }
The MultiMap
is relevant when one object is
associated with many different objects. A sensible example would be a
MultiMap
of people to the languages they speak
fluently, and the following example demonstrates such a
Map
:
MultiMap languageAbility = new MultiHashMap( ); languageAbility.put( "Tom", "French" ); languageAbility.put( "Chris", "Spanish" ); languageAbility.put( "Chris", "German" ); languageAbility.put( "John", "Arabic" ); languageAbility.put( "Tom", "Pashto" ); // What languages does Tom speak? Collection languages = (Collection) languageAbility.get("Tom"); Iterator languageIterator = languages.iterator( ); while( languageIterator.hasNext( ) ) { System.out.println( "Tom speaks " + languageIterator.next( ) ); }
If you had to locate people who were fluent in a given language, it
would be equally as valid to use languages as keys and names as
values. One could then query the MultiMap
for a
list of people who speak a certain language. If your system contains
two collections of objects that have a
many-to-many relationship,
these
relationships can
be managed with two instances of MultiMap
.
18.118.93.64