Parcourir la source

MapList now uses synchronised lists.

Added explicit documentation on synchronisation.
Minor code tidying and typo fixes.

Fixes issue 4344.

Change-Id: I92b691de235cb5da1ca83133cb6eac451c5973bd
Reviewed-on: http://gerrit.dmdirc.com/1452
Automatic-Compile: DMDirc Local Commits <dmdirc@googlemail.com>
Reviewed-by: Gregory Holmes <greg@dmdirc.com>
tags/0.6.5
Chris Smith il y a 14 ans
Parent
révision
2bc887dacc
1 fichiers modifiés avec 52 ajouts et 42 suppressions
  1. 52
    42
      src/com/dmdirc/util/MapList.java

+ 52
- 42
src/com/dmdirc/util/MapList.java Voir le fichier

@@ -24,6 +24,7 @@ package com.dmdirc.util;
24 24
 
25 25
 import java.util.ArrayList;
26 26
 import java.util.Collection;
27
+import java.util.Collections;
27 28
 import java.util.HashMap;
28 29
 import java.util.List;
29 30
 import java.util.Map;
@@ -32,13 +33,22 @@ import java.util.Set;
32 33
 /**
33 34
  * Wraps a Map&lt;S, List&lt;T&gt;&gt; with various convenience methods for
34 35
  * accessing the data. Implements a Map-like interface for easier transition.
35
- * 
36
+ * <p>
37
+ * <strong>Note that this implementation is not synchronized.</strong> If
38
+ * multiple threads access a <code>MapList</code> instance concurrently, and
39
+ * at least one of the threads modifies the map, it <em>must</em> be
40
+ * synchronized externally.
41
+ * <p>
42
+ * The <code>List</code>s used to back this map are synchronized using the
43
+ * {@link Collections#synchronizedList(java.util.List)} method, which requires
44
+ * manual synchronization in any code iterating over the values.
45
+ *
36 46
  * @param <S> the type of keys maintained by this map
37 47
  * @param <T> the type of mapped values
38 48
  * @author chris
39 49
  */
40
-public class MapList<S,T> {
41
-    
50
+public class MapList<S, T> {
51
+
42 52
     /** Our internal map. */
43 53
     protected final Map<S, List<T>> map;
44 54
 
@@ -51,17 +61,17 @@ public class MapList<S,T> {
51 61
 
52 62
     /**
53 63
      * Creates a new MapList with the values from the specified list.
54
-     * 
64
+     *
55 65
      * @param list The MapList whose values should be used
56 66
      */
57
-    public MapList(final MapList<S,T> list) {
67
+    public MapList(final MapList<S, T> list) {
58 68
         map = list.getMap();
59 69
     }
60 70
 
61 71
     /**
62 72
      * Determines if this MapList is empty. An empty MapList is one that either
63 73
      * contains no keys, or contains only keys which have no associated values.
64
-     * 
74
+     *
65 75
      * @return True if this MapList is empty, false otherwise
66 76
      */
67 77
     public boolean isEmpty() {
@@ -70,13 +80,13 @@ public class MapList<S,T> {
70 80
                 return false;
71 81
             }
72 82
         }
73
-        
83
+
74 84
         return true;
75 85
     }
76 86
 
77 87
     /**
78 88
      * Determines if this MapList contains the specified key.
79
-     * 
89
+     *
80 90
      * @param key The key to look for
81 91
      * @return True if this MapList contains the specified key, false otherwise
82 92
      */
@@ -87,10 +97,10 @@ public class MapList<S,T> {
87 97
     /**
88 98
      * Determines if this MapList contains the specified value as a child of
89 99
      * the specified key.
90
-     * 
100
+     *
91 101
      * @param key The key to search under
92 102
      * @param value The value to look for
93
-     * @return True if this MapList contains the specified key/value pair, 
103
+     * @return True if this MapList contains the specified key/value pair,
94 104
      * false otherwise
95 105
      */
96 106
     public boolean containsValue(final S key, final T value) {
@@ -99,53 +109,53 @@ public class MapList<S,T> {
99 109
 
100 110
     /**
101 111
      * Retrieves the list of values associated with the specified key.
102
-     * 
112
+     *
103 113
      * @param key The key whose values are being retrieved
104 114
      * @return The values belonging to the specified key
105 115
      */
106 116
     public List<T> get(final S key) {
107 117
         return map.get(key);
108 118
     }
109
-    
119
+
110 120
     /**
111 121
      * Retrieves the value at the specified offset of the specified key.
112
-     * 
122
+     *
113 123
      * @param key The key whose values are being retrieved
114 124
      * @param index The index of the value to retrieve
115 125
      * @return The specified value of the key
116
-     */    
126
+     */
117 127
     public T get(final S key, final int index) {
118 128
         return map.get(key).get(index);
119
-    }    
120
-    
129
+    }
130
+
121 131
     /**
122 132
      * Retrieves the list of values associated with the specified key, creating
123
-     * the key if neccessary.
124
-     * 
133
+     * the key if necessary.
134
+     *
125 135
      * @param key The key to retrieve
126 136
      * @return A list of the specified key's values
127 137
      */
128 138
     public List<T> safeGet(final S key) {
129 139
         if (!map.containsKey(key)) {
130
-            map.put(key, new ArrayList<T>());
140
+            map.put(key, Collections.synchronizedList(new ArrayList<T>()));
131 141
         }
132
-        
142
+
133 143
         return map.get(key);
134 144
     }
135
-    
145
+
136 146
     /**
137 147
      * Adds the specified key to the MapList.
138
-     * 
148
+     *
139 149
      * @param key The key to be added
140 150
      */
141 151
     public void add(final S key) {
142 152
         safeGet(key);
143
-    }    
153
+    }
144 154
 
145 155
     /**
146 156
      * Adds the specified value as a child of the specified key. If the key
147 157
      * didn't previous exist, it is created.
148
-     * 
158
+     *
149 159
      * @param key The key to which the value is being added
150 160
      * @param value The value to be added
151 161
      */
@@ -156,26 +166,26 @@ public class MapList<S,T> {
156 166
     /**
157 167
      * Adds the specified set of values to the specified key. If the key
158 168
      * didn't previous exist, it is created.
159
-     * 
169
+     *
160 170
      * @param key The key to which the value is being added
161 171
      * @param values The values to be added
162
-     */    
172
+     */
163 173
     public void add(final S key, final Collection<T> values) {
164 174
         safeGet(key).addAll(values);
165
-    }    
175
+    }
166 176
 
167 177
     /**
168 178
      * Removes the specified key and all of its values.
169
-     * 
179
+     *
170 180
      * @param key The key to remove
171
-     */    
181
+     */
172 182
     public void remove(final S key) {
173 183
         map.remove(key);
174 184
     }
175
-    
185
+
176 186
     /**
177 187
      * Removes the specified value from all keys.
178
-     * 
188
+     *
179 189
      * @param value The value to remove
180 190
      */
181 191
     public void removeFromAll(final T value) {
@@ -186,7 +196,7 @@ public class MapList<S,T> {
186 196
 
187 197
     /**
188 198
      * Removes the specified value from the specified key.
189
-     * 
199
+     *
190 200
      * @param key The key whose value is being removed
191 201
      * @param value The value to be removed
192 202
      */
@@ -194,7 +204,7 @@ public class MapList<S,T> {
194 204
         if (map.containsKey(key)) {
195 205
             map.get(key).remove(value);
196 206
         }
197
-    }    
207
+    }
198 208
 
199 209
     /**
200 210
      * Entirely clears this MapList.
@@ -202,19 +212,19 @@ public class MapList<S,T> {
202 212
     public void clear() {
203 213
         map.clear();
204 214
     }
205
-    
215
+
206 216
     /**
207 217
      * Clears all values of the specified key.
208
-     * 
218
+     *
209 219
      * @param key The key to be cleared
210 220
      */
211 221
     public void clear(final S key) {
212 222
         safeGet(key).clear();
213
-    }    
223
+    }
214 224
 
215 225
     /**
216 226
      * Returns the set of all keys belonging to this MapList.
217
-     * 
227
+     *
218 228
      * @return This MapList's keyset
219 229
      */
220 230
     public Set<S> keySet() {
@@ -223,26 +233,26 @@ public class MapList<S,T> {
223 233
 
224 234
     /**
225 235
      * Returns a collection of all values belonging to the specified key.
226
-     * 
236
+     *
227 237
      * @param key The key whose values are being sought
228 238
      * @return A collection of values belonging to the key
229 239
      */
230 240
     public Collection<T> values(final S key) {
231 241
         return map.get(key);
232 242
     }
233
-    
243
+
234 244
     /**
235 245
      * Retrieves the entry set for this MapList.
236
-     * 
246
+     *
237 247
      * @return This MapList's entry set
238 248
      */
239 249
     public Set<Map.Entry<S, List<T>>> entrySet() {
240 250
         return map.entrySet();
241 251
     }
242
-    
252
+
243 253
     /**
244 254
      * Retrieves the map behind this maplist.
245
-     * 
255
+     *
246 256
      * @return This MapList's map.
247 257
      */
248 258
     public Map<S, List<T>> getMap() {

Chargement…
Annuler
Enregistrer