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