/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

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