01: package fri.util.collections;
02:
03: import java.util.*;
04: import java.io.*;
05:
06: /**
07: A hashtable that holds a list of values instead of a single value for one key.
08: In any case the <i>get(Object)</i> method returns a List (Vector) of values.
09: Every new <i>put()</i> call adds to the list of values. The <i>remove()</i>
10: call removes the whole list of values at once.
11:
12: @author Fritz Ritzberger
13: */
14:
15: public class AggregatingHashtable extends Hashtable {
16: public AggregatingHashtable() {
17: super ();
18: }
19:
20: public AggregatingHashtable(int initialCapacity) {
21: super (initialCapacity);
22: }
23:
24: /**
25: Puts the passed value into a List (Vector) for given key, creates the list when necessary.
26: @return null if list was not yet existent, else the found list.
27: */
28: public Object put(Object key, Object value) {
29: List list = (List) super .get(key);
30: Object ret = null;
31:
32: if (list == null) {
33: list = createAggregationList();
34: super .put(key, list);
35: } else {
36: if (shouldAdd(list, value) == false)
37: return list;
38:
39: ret = list;
40: }
41:
42: list.add(value);
43: return ret;
44: }
45:
46: /** To be overridden for filtering values. */
47: protected boolean shouldAdd(List list, Object value) {
48: return true;
49: }
50:
51: /** To be overridden for allocation of special aggregation List types. */
52: protected List createAggregationList() {
53: return new ArrayList();
54: }
55:
56: /** Replaces the list of objects for a key by a new list, overriding aggregation. */
57: public void replace(Object key, List newList) {
58: super .put(key, newList);
59: }
60:
61: // Must adjust deserialization as put() will put value lists into newly provided lists
62: private void readObject(ObjectInputStream s) throws IOException,
63: ClassNotFoundException {
64: s.defaultReadObject();
65:
66: for (Iterator it = entrySet().iterator(); it.hasNext();) {
67: Map.Entry entry = (Map.Entry) it.next();
68: List list = (List) entry.getValue();
69: Object o = list.size() == 1 ? list.get(0) : null; // resolve the list that has been put by super.readObject()
70: if (o instanceof List) { // apache commons MultiHashMap came around with that problem only on JDK 1.2 and 1.3 ?
71: super.put(entry.getKey(), o);
72: }
73: }
74: }
75:
76: }
|