View Javadoc

1   package cz.cuni.amis.utils.maps;
2   
3   import java.util.Collection;
4   import java.util.HashMap;
5   import java.util.HashSet;
6   import java.util.Map;
7   import java.util.Set;
8   
9   import cz.cuni.amis.utils.collections.LazyMapValuesCollection;
10  
11  /**
12   * Abstract implementation of a lazy map.
13   * The values are created on-demand by the create method if they are not cached already.
14   * The keySet is kept updated however, only the values are lazy-generated.
15   * If you need to iterate over the map, but you don't actually need all the values, iterate over the keySet.
16   * @author srlok
17   *
18   * @param <KEY> KeyType
19   * @param <VALUE> ValueType
20   */
21  public abstract class AbstractLazyMap<KEY, VALUE> implements Map<KEY,VALUE> {
22  
23  	private Map<KEY,VALUE> cachedObjects = new HashMap<KEY,VALUE>(); 
24  	private Set<KEY> keySet = null;
25  	
26  	/**
27  	 * Creates the Mapped object based on its key. Every LazyMap must implement this.
28  	 * @param key
29  	 * @return
30  	 */
31  	protected abstract VALUE create( Object key );
32  	
33  	public AbstractLazyMap()
34  	{
35  		cachedObjects = new HashMap<KEY,VALUE>();
36  		keySet = new HashSet<KEY>();
37  	}
38  	
39  	public AbstractLazyMap( Set<KEY> entryKeySet )
40  	{
41  		this.keySet = entryKeySet;
42  	}
43  	
44  	public AbstractLazyMap( Map<KEY,VALUE> baseMap )
45  	{
46  		this.cachedObjects = baseMap;
47  		this.keySet = baseMap.keySet();
48  	}
49  	
50  	public void addKey( KEY key )
51  	{
52  		keySet.add(key);
53  	}
54  	
55  	@Override
56  	public void clear() {
57  		keySet.clear();
58  		cachedObjects.clear();
59  	}
60  	
61  	/**
62  	 * manually clears the cached objects
63  	 */
64  	public void clearCache()
65  	{
66  		cachedObjects.clear();
67  	}
68  
69  	@Override
70  	public boolean containsKey(Object key) {
71  		return keySet.contains( key );
72  	}
73  	
74  	public void setKeySet( Set<KEY> newKeySet)
75  	{
76  		this.clear();
77  		this.keySet = newKeySet;
78  	}
79  
80  	@Override
81  	/**
82  	 * Warning O(N) complexity, has to create all objects
83  	 */
84  	public boolean containsValue(Object value) 
85  	{
86  		for ( KEY key : keySet )
87  		{
88  			if ( this.get(key).equals(value) )
89  			{
90  				return true;
91  			}
92  		}
93  		return false;
94  	}
95  
96  	@Override
97  	public Set<java.util.Map.Entry<KEY, VALUE>> entrySet() {
98  		return cachedObjects.entrySet();
99  	}
100 
101 	@Override
102 	public synchronized VALUE get(Object key) {
103 		VALUE value = cachedObjects.get(key);
104 		if ( value != null ) return value;
105 		if ( keySet.contains(key) )
106 		{
107 			value = create(key);
108 			cachedObjects.put((KEY) key, value);
109 		}
110 		return value;
111 	}
112 
113 	@Override
114 	public boolean isEmpty() {
115 		return keySet.isEmpty();
116 	}
117 
118 	@Override
119 	public Set<KEY> keySet() {
120 		return keySet;
121 	}
122 
123 	@Override
124 	public VALUE put(KEY key, VALUE value) {
125 		keySet.add(key);
126 		return cachedObjects.put(key, value);
127 	}
128 
129 	@Override
130 	public void putAll(Map<? extends KEY, ? extends VALUE> m) {
131 		keySet.addAll( m.keySet() );
132 		cachedObjects.putAll(m);
133 	}
134 
135 	@Override
136 	public VALUE remove(Object key) {
137 		keySet.remove(key);
138 		return cachedObjects.remove(key);
139 	}
140 
141 	@Override
142 	public int size() {
143 		return keySet.size();
144 	}
145 
146 	@Override
147 	public Collection<VALUE> values() {
148 		return new LazyMapValuesCollection<VALUE,KEY>(this);
149 	}
150 	
151 	
152 
153 }