PageRenderTime 54ms CodeModel.GetById 15ms app.highlight 33ms RepoModel.GetById 1ms app.codeStats 0ms

/interpreter/tags/at2dist091109/src/edu/vub/util/MultiMap.java

http://ambienttalk.googlecode.com/
Java | 224 lines | 136 code | 33 blank | 55 comment | 16 complexity | 829c8cde9804f64ae2a7776800caf77e MD5 | raw file
  1/**
  2 * AmbientTalk/2 Project
  3 * MultiMap.java
  4 * (c) Programming Technology Lab, 2006 - 2007
  5 * Authors: Tom Van Cutsem & Stijn Mostinckx
  6 * 
  7 * Permission is hereby granted, free of charge, to any person
  8 * obtaining a copy of this software and associated documentation
  9 * files (the "Software"), to deal in the Software without
 10 * restriction, including without limitation the rights to use,
 11 * copy, modify, merge, publish, distribute, sublicense, and/or
 12 * sell copies of the Software, and to permit persons to whom the
 13 * Software is furnished to do so, subject to the following
 14 * conditions:
 15 *
 16 * The above copyright notice and this permission notice shall be
 17 * included in all copies or substantial portions of the Software.
 18 *
 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 21 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 22 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 23 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 26 * OTHER DEALINGS IN THE SOFTWARE.
 27 */
 28package edu.vub.util;
 29
 30import java.io.Serializable;
 31import java.util.Collection;
 32import java.util.HashMap;
 33import java.util.HashSet;
 34import java.util.Iterator;
 35import java.util.Map;
 36import java.util.Set;
 37
 38/**
 39 * A simple Map allowing one key to be associated with a Set of values.
 40 * 
 41 * @author smostinc
 42 */
 43public class MultiMap implements Map, Serializable, Cloneable {
 44
 45	private static final long serialVersionUID = -7040809979612963953L;
 46
 47	Map internal_ = new HashMap();
 48
 49	public void clear() {
 50		internal_.clear();
 51	}
 52
 53	public boolean containsKey(Object key) {
 54		return internal_.containsKey(key);
 55	}
 56
 57	public boolean containsValue(Object value) {
 58		Collection valuesSets = internal_.values();
 59		for (Iterator iter = valuesSets.iterator(); iter.hasNext();) {
 60			Set element = (Set) iter.next();
 61			if(element.contains(value))
 62				return true;
 63		}
 64		return false;
 65	}
 66
 67	public Set entrySet() {
 68		Set result = new HashSet();
 69		Set keys = internal_.keySet();
 70		for (Iterator iter = keys.iterator(); iter.hasNext();) {
 71			Object key = iter.next();
 72			Set values = (Set)get(key);
 73			for (Iterator iterator = values.iterator(); iterator.hasNext();) {
 74				Object value = iterator.next();
 75				result.add(new Entry(key, value));
 76			}
 77		}
 78		return result;
 79	}
 80
 81	public boolean equals(Object toBeCompared) {
 82		if(toBeCompared instanceof MultiMap) {
 83			return internal_.equals(((MultiMap)toBeCompared).internal_);
 84		}
 85		return false;
 86	}
 87
 88	/**
 89	 * @return a Set of values matching the key, or null if no entry is found
 90	 */
 91	public Object get(Object key) {
 92		return internal_.get(key);
 93	}
 94
 95	public int hashCode() {
 96		return internal_.hashCode();
 97	}
 98
 99
100	public boolean isEmpty() {
101		return internal_.isEmpty();
102	}
103
104	public Set keySet() {
105		return internal_.keySet();
106	}
107
108	public Object put(Object key, Object value) {
109		Object existingValues = internal_.get(key);
110		if(existingValues == null) { 
111			Set values = new HashSet();
112			values.add(value); 
113			internal_.put(key, values);
114		} else {
115			((Set)existingValues).add(value);
116		}
117		return null;
118	}
119
120	/**
121	 * Puts multivalued entries for one key
122	 */
123	public void putValues(Object key, Collection values) {
124		Object existingValues = internal_.get(key);
125		if(existingValues == null) {
126			Set setOfValues = new HashSet();
127			setOfValues.addAll(values); 
128			internal_.put(key, setOfValues);
129		} else {
130			((Set)existingValues).addAll(values);
131		}
132	}
133
134	public void putAll(Map toMerge) {
135		Set merged = toMerge.entrySet();
136		
137		// INFO this can probably be done more efficient
138		for (Iterator iter = merged.iterator(); iter.hasNext();) {
139			Map.Entry element = (Map.Entry) iter.next();
140			put(element.getKey(), element.getValue());
141		}
142	}
143
144	/**
145	 * Special case of putAll for merging MultiMaps
146	 */
147	public void putAll(MultiMap toMerge) {
148		Set keys = toMerge.keySet();		
149
150		// INFO this can probably be done more efficient
151		for (Iterator iter = keys.iterator(); iter.hasNext();) {
152			Object key = iter.next();
153			Collection values = (Collection)toMerge.get(key);
154			putValues(key, values);
155		}
156	}
157
158	/**
159	 * Returns a Set of the values that were associated 
160	 * with this key.
161	 * @see java.util.Map#remove(java.lang.Object)
162	 */
163	public Object remove(Object key) {
164		return internal_.remove(key);
165	}
166
167	/**
168	 * Removes a single value associated with a key 
169	 */
170	public boolean removeValue(Object key, Object value) {
171		Set values = (Set)internal_.get(key);
172		if(values != null) {
173			return values.remove(value);
174		} else {
175			return false;
176		}
177	}
178
179	public int size() {
180		return internal_.size();
181	}
182
183	/**
184	 * Returns a Set of Sets
185	 * @see java.util.Map#values()
186	 */
187	public Collection values() {
188		return internal_.values();
189	}
190
191	private void replaceValue(Object key, Object oldValue, Object newValue) {
192		Set values = (Set)internal_.get(key);
193		values.remove(oldValue);
194		values.add(newValue);
195	}
196
197	class Entry implements Map.Entry {
198
199		private final Object key_;
200		private Object value_;		
201
202		Entry(Object key, Object value) {
203			key_ = key;
204			value_ = value;
205		}
206
207		public Object getKey() {
208			return key_;
209		}
210
211		public Object getValue() {
212			return value_;
213		}
214
215		public Object setValue(Object newValue) {
216			Object result = value_;
217			value_ = newValue;
218			replaceValue(key_, result, value_);
219			return result;
220		}
221	}
222}
223
224