KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openlaszlo > utils > MultiMap


1 /* *****************************************************************************
2  * MultiMap.java
3  * ****************************************************************************/

4
5 /* J_LZ_COPYRIGHT_BEGIN *******************************************************
6 * Copyright 2001-2004 Laszlo Systems, Inc. All Rights Reserved. *
7 * Use is subject to license terms. *
8 * J_LZ_COPYRIGHT_END *********************************************************/

9
10 package org.openlaszlo.utils;
11
12 import java.util.Collection JavaDoc;
13 import java.util.Hashtable JavaDoc;
14 import java.util.HashSet JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.Map JavaDoc;
17 import java.util.Set JavaDoc;
18
19 /** Partial implementation of a map that stores multiple values for a single
20  * key. */

21 public class MultiMap
22     implements Map JavaDoc
23 {
24     /** Table to store information; each node may hold multiple values */
25     Hashtable JavaDoc mTable = new Hashtable JavaDoc();
26
27     /** Returns a Set view of the keys contained in this Hashtable. The Set is
28      * backed by the Hashtable, so changes to the Hashtable are reflected in the
29      * Set, and vice-versa. The Set supports element removal (which removes the
30      * corresponding entry from the Hashtable), but not element addition. */

31     public Set JavaDoc keySet()
32     {
33         return mTable.keySet();
34     }
35
36     /** Returns the set of values to which the specified key is mapped in this
37      * multimap.
38      * @param key key in the map
39      * @return set of values to which the specified key is mapped; null if none
40      * is found */

41     public Object JavaDoc get(Object JavaDoc key)
42     {
43         return mTable.get(key);
44     }
45
46     /** Maps the specified key to the specified value in this map. The key
47      * and value may not be null.
48      * @param key the map key
49      * @param val the value
50      * @return the set that val was added to */

51     public Object JavaDoc put(Object JavaDoc key, Object JavaDoc val)
52     {
53         Set JavaDoc valSet = (Set JavaDoc)mTable.get(key);
54         if (valSet == null) {
55             valSet = new HashSet JavaDoc();
56             mTable.put(key, valSet);
57         }
58         valSet.add(val);
59         return valSet;
60     }
61
62     /** Remove a particular value associated with key.
63      * @param key the key to check for associated value
64      * @param val the actual value to remove
65      * @return the value to which the key had be mapped in this mulimap or
66      * null, if the key did not have a mapping */

67     public Object JavaDoc remove(Object JavaDoc key, Object JavaDoc val)
68     {
69         Object JavaDoc ret = null;
70         Set JavaDoc valSet = (Set JavaDoc)mTable.get(key);
71         if (valSet != null) {
72             if (valSet.remove(val))
73                 ret = val;
74             if (valSet.isEmpty())
75                 mTable.remove(key);
76         }
77         return ret;
78     }
79
80     /** Remove all values associated with key.
81      * @param key the key to remove
82      * @return the set of values removed that were associated with key */

83     public Object JavaDoc remove(Object JavaDoc key)
84     {
85         return mTable.remove(key);
86     }
87
88     /** Returns a Collection view of the values contained in this Hashtable. The
89      * Collection is backed by the Hashtable, so changes to the Hashtable are
90      * reflected in the Collection, and vice-versa. The Collection supports
91      * element removal (which removes the corresponding entry from the
92      * Hashtable), but not element addition.
93      * @return a collection view of the values contained in this map */

94     public Collection JavaDoc values()
95     {
96         return mTable.values();
97     }
98
99
100     /** Returns the number of key-set mappings in this map. If the map contains
101      * more than Integer.MAX_VALUE elements, returns Integer.MAX_VALUE.
102      * @return the number of key-value mappings in this map */

103     public int size()
104     {
105         return mTable.size();
106     }
107
108     /** Returns <code>true</code> if this map contains no key-value mappings.
109      * @return <code>true</code> if this map contains no key-value mappings */

110     public boolean isEmpty()
111     {
112         return mTable.isEmpty();
113     }
114
115     /** Returns true if this map contains a mapping for the specified key.
116      * @param key key whose presence in this map is to be tested
117      * @return true if this map contains a mapping for the specified key.
118      */

119     public boolean containsKey(Object JavaDoc key)
120     {
121         return mTable.containsKey(key);
122     }
123
124     /** Returns <code>true</code> if this map maps one or more keys to the
125      * specified value. More formally, returns true if and only if this map
126      * contains at least one mapping to a value v such that <code>(value==null ?
127      * v==null : value.equals(v))</code>. This operation will probably require
128      * time linear in the map size for most implementations of the Map
129      * interface.
130      * @param value value whose presence in this map is to be tested
131      * @return <code>true</code> if this map maps one or more keys to the
132      * specified value */

133     public boolean containsValue(Object JavaDoc value)
134     {
135         Collection JavaDoc c = mTable.values();
136         Iterator JavaDoc iter = c.iterator();
137         while (iter.hasNext()) {
138             Set JavaDoc set = (Set JavaDoc)iter.next();
139             if (set.contains(value))
140                 return true;
141         }
142         return false;
143     }
144
145     /** Remove value from map and return keys this value was associated with.
146      * @param value value to remove
147      * @return set of keys associated with removed value; null, if none was
148      * found */

149     public Set JavaDoc removeValue(Object JavaDoc value)
150     {
151         Set JavaDoc keySet = new HashSet JavaDoc();
152         Iterator JavaDoc iter = ((Set JavaDoc)mTable.entrySet()).iterator();
153         while (iter.hasNext()) {
154             Map.Entry JavaDoc entry = (Map.Entry JavaDoc)iter.next();
155             Set JavaDoc set = (Set JavaDoc)entry.getValue();
156             if (set.contains(value)) {
157                 keySet.add(entry.getKey());
158                 set.remove(value);
159                 // if set is empty, remove the key-value entry in table
160
if (set.isEmpty())
161                     iter.remove();
162             }
163         }
164         return (!keySet.isEmpty()?keySet:null);
165     }
166
167
168     /** Unsupported. */
169     public void putAll(Map JavaDoc m)
170     {
171         throw new UnsupportedOperationException JavaDoc();
172     }
173
174     /** Unsupported. */
175     public void clear()
176     {
177         throw new UnsupportedOperationException JavaDoc();
178     }
179
180     /** Returns a set view of the mappings contained in this map. Each element
181      * in the returned set is a Map.Entry. The set is backed by the map, so
182      * changes to the map are reflected in the set, and vice-versa. If the map
183      * is modified while an iteration over the set is in progress, the results
184      * of the iteration are undefined. The set supports element removal, which
185      * removes the corresponding mapping from the map, via the Iterator.remove,
186      * Set.remove, removeAll, retainAll and clear operations. It does not
187      * support the add or addAll operations.
188      * @return a set view of the mappings contained in this map */

189     public Set JavaDoc entrySet()
190     {
191         return mTable.entrySet();
192     }
193
194 }
195
Popular Tags