PageRenderTime 57ms CodeModel.GetById 17ms app.highlight 34ms RepoModel.GetById 1ms app.codeStats 0ms

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

http://ambienttalk.googlecode.com/
Java | 197 lines | 136 code | 33 blank | 28 comment | 16 complexity | a827cfb17a4e66c3c26bd5bb911bd7ff MD5 | raw file
  1package edu.vub.util;
  2
  3import java.io.Serializable;
  4import java.util.Collection;
  5import java.util.HashMap;
  6import java.util.HashSet;
  7import java.util.Iterator;
  8import java.util.Map;
  9import java.util.Set;
 10
 11/**
 12 * A simple Map allowing one key to be associated with a Set of values.
 13 * 
 14 * @author smostinc
 15 */
 16public class MultiMap implements Map, Serializable, Cloneable {
 17
 18	private static final long serialVersionUID = -7040809979612963953L;
 19
 20	Map internal_ = new HashMap();
 21
 22	public void clear() {
 23		internal_.clear();
 24	}
 25
 26	public boolean containsKey(Object key) {
 27		return internal_.containsKey(key);
 28	}
 29
 30	public boolean containsValue(Object value) {
 31		Collection valuesSets = internal_.values();
 32		for (Iterator iter = valuesSets.iterator(); iter.hasNext();) {
 33			Set element = (Set) iter.next();
 34			if(element.contains(value))
 35				return true;
 36		}
 37		return false;
 38	}
 39
 40	public Set entrySet() {
 41		Set result = new HashSet();
 42		Set keys = internal_.keySet();
 43		for (Iterator iter = keys.iterator(); iter.hasNext();) {
 44			Object key = iter.next();
 45			Set values = (Set)get(key);
 46			for (Iterator iterator = values.iterator(); iterator.hasNext();) {
 47				Object value = iterator.next();
 48				result.add(new Entry(key, value));
 49			}
 50		}
 51		return result;
 52	}
 53
 54	public boolean equals(Object toBeCompared) {
 55		if(toBeCompared instanceof MultiMap) {
 56			return internal_.equals(((MultiMap)toBeCompared).internal_);
 57		}
 58		return false;
 59	}
 60
 61	/**
 62	 * @return a Set of values matching the key, or null if no entry is found
 63	 */
 64	public Object get(Object key) {
 65		return internal_.get(key);
 66	}
 67
 68	public int hashCode() {
 69		return internal_.hashCode();
 70	}
 71
 72
 73	public boolean isEmpty() {
 74		return internal_.isEmpty();
 75	}
 76
 77	public Set keySet() {
 78		return internal_.keySet();
 79	}
 80
 81	public Object put(Object key, Object value) {
 82		Object existingValues = internal_.get(key);
 83		if(existingValues == null) { 
 84			Set values = new HashSet();
 85			values.add(value); 
 86			internal_.put(key, values);
 87		} else {
 88			((Set)existingValues).add(value);
 89		}
 90		return null;
 91	}
 92
 93	/**
 94	 * Puts multivalued entries for one key
 95	 */
 96	public void putValues(Object key, Collection values) {
 97		Object existingValues = internal_.get(key);
 98		if(existingValues == null) {
 99			Set setOfValues = new HashSet();
100			setOfValues.addAll(values); 
101			internal_.put(key, setOfValues);
102		} else {
103			((Set)existingValues).addAll(values);
104		}
105	}
106
107	public void putAll(Map toMerge) {
108		Set merged = toMerge.entrySet();
109		
110		// INFO this can probably be done more efficient
111		for (Iterator iter = merged.iterator(); iter.hasNext();) {
112			Map.Entry element = (Map.Entry) iter.next();
113			put(element.getKey(), element.getValue());
114		}
115	}
116
117	/**
118	 * Special case of putAll for merging MultiMaps
119	 */
120	public void putAll(MultiMap toMerge) {
121		Set keys = toMerge.keySet();		
122
123		// INFO this can probably be done more efficient
124		for (Iterator iter = keys.iterator(); iter.hasNext();) {
125			Object key = iter.next();
126			Collection values = (Collection)toMerge.get(key);
127			putValues(key, values);
128		}
129	}
130
131	/**
132	 * Returns a Set of the values that were associated 
133	 * with this key.
134	 * @see java.util.Map#remove(java.lang.Object)
135	 */
136	public Object remove(Object key) {
137		return internal_.remove(key);
138	}
139
140	/**
141	 * Removes a single value associated with a key 
142	 */
143	public boolean removeValue(Object key, Object value) {
144		Set values = (Set)internal_.get(key);
145		if(values != null) {
146			return values.remove(value);
147		} else {
148			return false;
149		}
150	}
151
152	public int size() {
153		return internal_.size();
154	}
155
156	/**
157	 * Returns a Set of Sets
158	 * @see java.util.Map#values()
159	 */
160	public Collection values() {
161		return internal_.values();
162	}
163
164	private void replaceValue(Object key, Object oldValue, Object newValue) {
165		Set values = (Set)internal_.get(key);
166		values.remove(oldValue);
167		values.add(newValue);
168	}
169
170	class Entry implements Map.Entry {
171
172		private final Object key_;
173		private Object value_;		
174
175		Entry(Object key, Object value) {
176			key_ = key;
177			value_ = value;
178		}
179
180		public Object getKey() {
181			return key_;
182		}
183
184		public Object getValue() {
185			return value_;
186		}
187
188		public Object setValue(Object newValue) {
189			Object result = value_;
190			value_ = newValue;
191			replaceValue(key_, result, value_);
192			return result;
193		}
194	}
195}
196
197