source: josm/trunk/src/org/openstreetmap/josm/tools/MultiMap.java@ 4067

Last change on this file since 4067 was 3674, checked in by bastiK, 13 years ago

Replace Bag by MultiMap.
Both collections are quite similar, but there is a technical difference: Bag is backed by an ArrayList and MultiMap by a LinkedHashSet. So with a Bag you could map a key multiple times to a certain value. I haven't found any usage where this behaviour is required or intended.
Also there could be a certain performance drawback with LinkedHashSet compared to ArrayList. However in the typical validator use case the value collection represents duplicate or crossing ways, so the number of elements is usually 1 or 2 and mostly smaller than the initial capacity (LHS=16, AL=10). (But I could have overlooked some use cases.)

  • Property svn:eol-style set to native
File size: 2.9 KB
Line 
1// License: GPL. See LICENSE file for details.
2package org.openstreetmap.josm.tools;
3
4import java.util.Collection;
5import java.util.HashMap;
6import java.util.LinkedHashSet;
7import java.util.Map;
8import java.util.Map.Entry;
9import java.util.Set;
10
11/**
12 * MultiMap - maps keys to multiple values
13 *
14 * Corresponds to Google guava LinkedHashMultimap and Apache Collections MultiValueMap
15 * but it is an independent (simplistic) implementation.
16 *
17 */
18public class MultiMap<A, B> {
19
20 private final Map<A, LinkedHashSet<B>> map;
21
22 public MultiMap() {
23 map = new HashMap<A, LinkedHashSet<B>>();
24 }
25
26 public MultiMap(int capacity) {
27 map = new HashMap<A, LinkedHashSet<B>>(capacity);
28 }
29
30 /**
31 * Map a key to a value. Can be called multiple times with the same key, but different value.
32 */
33 public void put(A key, B value) {
34 LinkedHashSet<B> vals = map.get(key);
35 if (vals == null) {
36 vals = new LinkedHashSet<B>();
37 map.put(key, vals);
38 }
39 vals.add(value);
40 }
41
42 /**
43 * Put a key that maps to nothing. (Only if it is not already in the map)
44 * Afterwards containsKey(key) will return true and get(key) will return
45 * an empty Set instead of null.
46 */
47 public void putVoid(A key) {
48 if (map.containsKey(key))
49 return;
50 map.put(key, new LinkedHashSet<B>());
51 }
52
53 /**
54 * Get the keySet
55 */
56 public Set<A> keySet() {
57 return map.keySet();
58 }
59
60 /**
61 * Return the Set associated with the given key. Result is null if
62 * nothing has been mapped to this key. Modifications of the returned list
63 * changes the underling map, but you should better not do that.
64 */
65 public Set<B> get(A key) {
66 return map.get(key);
67 }
68
69 /**
70 * Like get, but returns an empty Set if nothing has been mapped to the key.
71 */
72 public LinkedHashSet<B> getValues(A key) {
73 if (!map.containsKey(key))
74 return new LinkedHashSet<B>();
75 return map.get(key);
76 }
77
78 public boolean isEmpty() {
79 return map.isEmpty();
80 }
81
82 public boolean containsKey(A key) {
83 return map.containsKey(key);
84 }
85
86 /**
87 * Returns true if the multimap contains a value for a key
88 * @param key The key
89 * @param value The value
90 * @return true if the key contains the value
91 */
92 public boolean contains(A key, B value) {
93 Set<B> values = get(key);
94 return (values == null) ? false : values.contains(value);
95 }
96
97 public void clear() {
98 map.clear();
99 }
100
101 public Set<Entry<A, LinkedHashSet<B>>> entrySet() {
102 return map.entrySet();
103 }
104
105 /**
106 * number of keys
107 */
108 public int size() {
109 return map.size();
110 }
111
112 /**
113 * returns a collection of all value sets
114 */
115 public Collection<LinkedHashSet<B>> values() {
116 return map.values();
117 }
118}
Note: See TracBrowser for help on using the repository browser.