1 package dolda.jsvc.util;
3 import dolda.jsvc.MultiMap;
6 public class WrappedMultiMap<K, V> implements MultiMap<K, V> {
7 private Map<K, Collection<V>> bk;
8 private EntrySet entryset;
11 public WrappedMultiMap(Map<K, Collection<V>> bk) {
15 private V get1(Collection<V> vs) {
18 Iterator<V> i = vs.iterator();
29 public boolean containsKey(Object key) {
30 Collection<V> vs = bk.get(key);
33 return(!vs.isEmpty());
36 public boolean equals(Object o) {
40 public V get(Object key) {
41 return(get1(bk.get(key)));
44 public Collection<V> values(K key) {
45 Collection<V> vs = bk.get(key);
47 vs = new LinkedList<V>();
53 public int hashCode() {
54 return(bk.hashCode());
57 public boolean isEmpty() {
58 return(values().isEmpty());
61 public Set<K> keySet() {
65 public V put(K key, V value) {
66 Collection<V> vs = new LinkedList<V>();
69 return(get1(bk.put(key, vs)));
72 public void add(K key, V value) {
74 values(key).add(value);
77 public Collection<V> putValues(K key, Collection<V> values) {
79 return(bk.put(key, values));
82 private class DumbEntry implements Map.Entry<K, V> {
86 public DumbEntry(K key, V value) {
91 public boolean equals(Object o) {
92 if(!(o instanceof Map.Entry))
94 Map.Entry oe = (Map.Entry)o;
95 return(((key == null)?(oe.getKey() == null):key.equals(oe.getKey())) &&
96 ((value == null)?(oe.getValue() == null):value.equals(oe.getValue())));
103 public V getValue() {
107 public int hashCode() {
108 return(key.hashCode() + value.hashCode());
111 public V setValue(V value) {
112 throw(new UnsupportedOperationException());
116 private class EntrySet extends AbstractSet<Map.Entry<K, V>> {
117 public Iterator<Map.Entry<K, V>> iterator() {
118 return(new Iterator<Map.Entry<K, V>>() {
119 private Iterator<Map.Entry<K, Collection<V>>> bki = bk.entrySet().iterator();
121 private Iterator<V> vsi = null;
123 public boolean hasNext() {
124 if((vsi != null) && vsi.hasNext())
126 return(bki.hasNext());
129 public Map.Entry<K, V> next() {
130 if((vsi == null) || !vsi.hasNext()) {
131 Map.Entry<K, Collection<V>> ne = bki.next();
132 curkey = ne.getKey();
133 vsi = ne.getValue().iterator();
135 return(new DumbEntry(curkey, vsi.next()));
138 public void remove() {
146 return(WrappedMultiMap.this.size());
149 public boolean remove(Object o) {
151 return(WrappedMultiMap.this.remove(o) != null);
154 public void clear() {
160 private class Values extends AbstractCollection<V> {
161 public Iterator<V> iterator() {
162 return(new Iterator<V>() {
163 Iterator<Map.Entry<K, V>> bki = WrappedMultiMap.this.entrySet().iterator();
165 public boolean hasNext() {
166 return(bki.hasNext());
170 return(bki.next().getValue());
173 public void remove() {
181 return(WrappedMultiMap.this.size());
184 public boolean contains(Object o) {
185 return(containsValue(o));
188 public void clear() {
194 public Set<Map.Entry<K, V>> entrySet() {
196 entryset = new EntrySet();
200 public Collection<V> values() {
202 values = new Values();
206 public void putAll(Map<? extends K, ? extends V> m) {
208 for(Map.Entry<? extends K, ? extends V> e : m.entrySet())
209 add(e.getKey(), e.getValue());
212 public V remove(Object key) {
214 return(get1(bk.remove(key)));
217 public boolean containsValue(Object value) {
218 for(Collection<V> vs : bk.values()) {
219 if(vs.contains(value))
227 for(Collection<V> vs : bk.values())
232 protected void modified() {}
234 public String toString() {
235 StringBuilder buf = new StringBuilder();
237 for(Map.Entry<K, V> e : entrySet()) {
239 buf.append(e.getKey().toString());
241 buf.append(e.getValue().toString());
245 return(buf.toString());