blob: 76726386b9ba55233bce19e9a572d037d7ef402e [file] [log] [blame]
Stuart McCulloch3fdcd852011-10-17 10:31:43 +00001package aQute.lib.collections;
2
3import java.util.*;
4
5public class MultiMap<K,V> extends HashMap<K,Set<V>> {
6 private static final long serialVersionUID = 1L;
7 final Set<V> EMPTY = Collections.emptySet();
8
9 public boolean add( K key, V value ) {
10 Set<V> set = get(key);
11 if ( set == null) {
12 set=new HashSet<V>();
13 put(key,set);
14 }
15 return set.add(value);
16 }
17
18 public boolean addAll( K key, Collection<V> value ) {
19 Set<V> set = get(key);
20 if ( set == null) {
21 set=new HashSet<V>();
22 put(key,set);
23 }
24 return set.addAll(value);
25 }
26
27 public boolean remove( K key, V value ) {
28 Set<V> set = get(key);
29 if ( set == null) {
30 return false;
31 }
32 boolean result = set.remove(value);
33 if ( set.isEmpty())
34 remove(key);
35 return result;
36 }
37
38 public boolean removeAll( K key, Collection<V> value ) {
39 Set<V> set = get(key);
40 if ( set == null) {
41 return false;
42 }
43 boolean result = set.removeAll(value);
44 if ( set.isEmpty())
45 remove(key);
46 return result;
47 }
48
49 public Iterator<V> iterate(K key) {
50 Set<V> set = get(key);
51 if ( set == null)
52 return EMPTY.iterator();
53 else
54 return set.iterator();
55 }
56
57 public Iterator<V> all() {
58 return new Iterator<V>() {
59 Iterator<Set<V>> master = values().iterator();
60 Iterator<V> current = null;
61
62 public boolean hasNext() {
63 if ( current == null || !current.hasNext()) {
64 if ( master.hasNext()) {
65 current = master.next().iterator();
66 return current.hasNext();
67 }
68 return false;
69 }
70 return true;
71 }
72
73 public V next() {
74 return current.next();
75 }
76
77 public void remove() {
78 current.remove();
79 }
80
81 };
82 }
83}