1 19 20 25 26 27 package soot.util; 28 29 import java.util.*; 30 31 public class IterableMap implements Map 32 { 33 private HashMap content_map, back_map; 34 private HashChain key_chain, value_chain; 35 36 public IterableMap() 37 { 38 this( 7, 0.7f); 39 } 40 41 public IterableMap( int initialCapacity) 42 { 43 this( initialCapacity, 0.7f); 44 } 45 46 public IterableMap( int initialCapacity, float loadFactor) 47 { 48 content_map = new HashMap( initialCapacity, loadFactor); 49 back_map = new HashMap( initialCapacity, loadFactor); 50 key_chain = new HashChain(); 51 value_chain = new HashChain(); 52 } 53 54 public void clear() 55 { 56 Iterator kcit = key_chain.iterator(); 57 while (kcit.hasNext()) 58 content_map.remove( kcit.next()); 59 60 Iterator vcit = value_chain.iterator(); 61 while (vcit.hasNext()) 62 back_map.remove( vcit.next()); 63 64 key_chain.clear(); 65 value_chain.clear(); 66 } 67 68 public Iterator iterator() 69 { 70 return key_chain.iterator(); 71 } 72 73 public boolean containsKey(Object key) 74 { 75 return key_chain.contains( key); 76 } 77 78 public boolean containsValue(Object value) 79 { 80 return value_chain.contains( value); 81 } 82 83 public Set entrySet() 84 { 85 return content_map.entrySet(); 86 } 87 88 public boolean equals( Object o) 89 { 90 if (o == this) 91 return true; 92 93 if ((o instanceof IterableMap) == false) 94 return false; 95 96 IterableMap other = (IterableMap) o; 97 98 if (key_chain.equals( other.key_chain) == false) 99 return false; 100 101 Iterator kcit = key_chain.iterator(); 103 while (kcit.hasNext()) { 104 Object ko = kcit.next(); 105 106 if (other.content_map.get( ko) != content_map.get( ko)) 107 return false; 108 } 109 110 return true; 111 } 112 113 public Object get( Object key) 114 { 115 return content_map.get( key); 116 } 117 118 public int hashCode() 119 { 120 return content_map.hashCode(); 121 } 122 123 public boolean isEmpty() 124 { 125 return key_chain.isEmpty(); 126 } 127 128 private transient Set keySet = null; 129 private transient Set valueSet = null; 130 private transient Collection values = null; 131 132 public Set keySet() 133 { 134 if (keySet == null) { 135 keySet = new AbstractSet() { 136 public Iterator iterator() { 137 return key_chain.iterator(); 138 } 139 public int size() { 140 return key_chain.size(); 141 } 142 public boolean contains(Object o) { 143 return key_chain.contains(o); 144 } 145 public boolean remove(Object o) { 146 if (key_chain.contains(o) == false) { 147 return false; 148 } 149 150 if (IterableMap.this.content_map.get( o) == null) { 151 IterableMap.this.remove(o); 152 return true; 153 } 154 155 return (IterableMap.this.remove(o) != null); 156 } 157 public void clear() { 158 IterableMap.this.clear(); 159 } 160 }; 161 } 162 return keySet; 163 } 164 165 public Set valueSet() 166 { 167 if (valueSet == null) { 168 valueSet = new AbstractSet() { 169 public Iterator iterator() { 170 return value_chain.iterator(); 171 } 172 public int size() { 173 return value_chain.size(); 174 } 175 public boolean contains(Object o) { 176 return value_chain.contains(o); 177 } 178 179 public boolean remove(Object o) { 180 if (value_chain.contains( o) == false) { 181 return false; 182 } 183 184 HashChain c = (HashChain) IterableMap.this.back_map.get( o); 185 Iterator it = c.snapshotIterator(); 186 while (it.hasNext()) { 187 Object ko = it.next(); 188 189 if (IterableMap.this.content_map.get( o) == null) { 190 IterableMap.this.remove(ko); 191 } 192 else if (IterableMap.this.remove( ko) == null) { 193 return false; 194 } 195 } 196 return true; 197 } 198 public void clear() { 199 IterableMap.this.clear(); 200 } 201 }; 202 } 203 return valueSet; 204 } 205 206 public Object put( Object key, Object value) 207 { 208 if (key_chain.contains( key)) { 209 210 Object old_value = content_map.get( key); 211 212 if (old_value == value) 213 return value; 214 215 HashChain kc = (HashChain) back_map.get( old_value); 216 kc.remove( key); 217 218 if (kc.isEmpty()) { 219 value_chain.remove( old_value); 220 back_map.remove( old_value); 221 } 222 223 kc = (HashChain) back_map.get( value); 224 if (kc == null) { 225 kc = new HashChain(); 226 back_map.put( value, kc); 227 value_chain.add( value); 228 } 229 kc.add( key); 230 231 return old_value; 232 233 } 234 else { 235 236 key_chain.add(key); 237 content_map.put( key, value); 238 239 HashChain kc = (HashChain) back_map.get( value); 240 if (kc == null) { 241 kc = new HashChain(); 242 back_map.put( value, kc); 243 value_chain.add( value); 244 } 245 kc.add( key); 246 247 return null; 248 } 249 } 250 251 public void putAll( Map t) 252 { 253 Iterator kit = (t instanceof IterableMap) ? ((IterableMap) t).key_chain.iterator() : t.keySet().iterator(); 254 255 while (kit.hasNext()) { 256 Object key = kit.next(); 257 put( key, t.get( key)); 258 } 259 } 260 261 262 public Object remove( Object key) 263 { 264 if (key_chain.contains( key) == false) 265 return null; 266 267 key_chain.remove( key); 268 Object value = content_map.remove( key); 269 HashChain c = (HashChain) back_map.get( value); 270 c.remove( key); 271 if (c.size() == 0) 272 back_map.remove( value); 273 274 return value; 275 } 276 277 public int size() 278 { 279 return key_chain.size(); 280 } 281 282 public Collection values() 283 { 284 if (values==null) { 285 values = new AbstractCollection() { 286 public Iterator iterator() { 287 return new Mapping_Iterator( IterableMap.this.key_chain, IterableMap.this.content_map); 288 } 289 public int size() { 290 return key_chain.size(); 291 } 292 public boolean contains(Object o) { 293 return value_chain.contains(o); 294 } 295 public void clear() { 296 IterableMap.this.clear(); 297 } 298 }; 299 } 300 return values; 301 } 302 303 public class Mapping_Iterator implements Iterator 304 { 305 private Iterator it; 306 private HashMap m; 307 308 public Mapping_Iterator( HashChain c, HashMap m) 309 { 310 it = c.iterator(); 311 this.m = m; 312 } 313 314 public boolean hasNext() 315 { 316 return it.hasNext(); 317 } 318 319 public Object next() throws NoSuchElementException 320 { 321 return m.get( it.next()); 322 } 323 324 public void remove() throws UnsupportedOperationException 325 { 326 throw new UnsupportedOperationException ("You cannot remove from an Iterator on the values() for an IterableMap."); 327 } 328 } 329 330 } 331 | Popular Tags |