View Javadoc

1   package cz.cuni.amis.utils.maps;
2   
3   import java.util.Collections;
4   import java.util.HashMap;
5   import java.util.Map;
6   
7   /**
8    * Map containing other maps. Whenever a map under some key is requested and does not exists,
9    * the HashMapMap automatically creates new one.
10   * <p><p>
11   * The implementation is unsynchronized, created maps are synchronized (just iteration over the inner-map must
12   * be synchronized by the user as described in Java(tm) documentation).
13   * 
14   * @author Jimmy
15   *
16   * @param <PRIMARY_KEY>
17   * @param <SECONDARY_KEY>
18   * @param <ITEM>
19   */
20  public class HashMapMap<PRIMARY_KEY, SECONDARY_KEY, ITEM> 
21  	extends HashMap<PRIMARY_KEY, Map<SECONDARY_KEY, ITEM>> {
22  	
23  	/**
24  	 * 
25  	 */
26  	private static final long serialVersionUID = -4541899270970246601L;
27  	int secondaryCapacity;
28  	
29  	public HashMapMap() {
30  		secondaryCapacity = 16; 
31  	}
32  	
33  	public HashMapMap(int primaryCapacity, int secondaryCapacity)
34  	{
35  		super(primaryCapacity);
36  		this.secondaryCapacity = secondaryCapacity;
37  	}
38  
39  	/**
40  	 * The get method ensures that the requested map under primaryKey always exists!
41  	 * 
42  	 * @param primaryKey must be instance of PRIMARY_KEY
43  	 */
44  	@Override
45  	public Map<SECONDARY_KEY, ITEM> get(Object primaryKey) {
46  		Map<SECONDARY_KEY, ITEM> map = super.get(primaryKey);
47  		if (map != null) return map;
48  		map = Collections.synchronizedMap(new HashMap<SECONDARY_KEY, ITEM>(secondaryCapacity));
49  		super.put((PRIMARY_KEY)primaryKey, map);
50  		return map;
51  	}
52  	
53  	/**
54  	 * Returns an item under primary and secondary key if exists (otherwise a null is returned).
55  	 * @param primaryKey
56  	 * @param secondaryKey
57  	 * @return
58  	 */
59  	public ITEM get(PRIMARY_KEY primaryKey, SECONDARY_KEY secondaryKey) {
60  		return get(primaryKey).get(secondaryKey);
61  	}
62  	
63  	/**
64  	 * Inserts an item under primary and then secondary key.
65  	 * @param primaryKey
66  	 * @param secondaryKey
67  	 * @param item
68  	 */
69  	public void put(PRIMARY_KEY primaryKey, SECONDARY_KEY secondaryKey, ITEM item) {
70  		get(primaryKey).put(secondaryKey, item);
71  	}
72  	
73  	/**
74  	 * Remove returns the removed item, if item was non-existent, it returns empty map. 
75  	 * @param primaryKey
76  	 * @return
77  	 */
78  	@Override
79  	public Map<SECONDARY_KEY, ITEM> remove(Object primaryKey) {
80  		Map<SECONDARY_KEY, ITEM> map = super.remove(primaryKey);
81  		if (map != null) return map;
82  		return Collections.synchronizedMap(new HashMap<SECONDARY_KEY, ITEM>(secondaryCapacity));
83  	}
84  
85  	/**
86  	 * Removes an item from the map.
87  	 * @param primaryKey
88  	 * @param secondaryKey
89  	 * @return
90  	 */
91  	public ITEM remove(PRIMARY_KEY primaryKey, SECONDARY_KEY secondaryKey) {
92  		return get(primaryKey).remove(secondaryKey);
93  	}
94  
95  }