|
SimpleMapImpl |
|
1 /* 2 * SimpleMapImpl.java 3 * 4 * Copyright (c) 2001, The University of Sheffield. 5 * 6 * This file is part of GATE (see http://gate.ac.uk/), and is free 7 * software, licenced under the GNU Library General Public License, 8 * Version 2, June 1991 (in the distribution as file licence.html, 9 * and also available at http://gate.ac.uk/gate/licence.html). 10 * 11 * D.Ognyanoff, 5/Nov/2001 12 * 13 * $Id: SimpleMapImpl.java,v 1.5 2001/11/20 12:25:51 kalina Exp $ 14 */ 15 16 package gate.util; 17 18 import java.util.*; 19 20 /** 21 * Implements Map interface in using less memory. Very simple but usefull 22 * for small number of items on it. 23 */ 24 25 class SimpleMapImpl implements Map, java.lang.Cloneable, java.io.Serializable { 26 27 /** 28 * The capacity of the map 29 */ 30 int m_capacity=3; 31 32 /** 33 * The current number of elements of the map 34 */ 35 int m_size=0; 36 37 /** 38 * Array keeping the keys of the entries in the map. It is "synchrnized" 39 * with the m_values array - the Nth position in both arrays correspond 40 * to one and the same entry 41 */ 42 Object m_keys[]; 43 /** 44 * Array keeping the values of the entries in the map. It is "synchrnized" 45 * with the m_keys array - the Nth position in both arrays correspond 46 * to one and the same entry 47 */ 48 Object m_values[]; 49 50 public SimpleMapImpl() { 51 m_keys = new Object[m_capacity]; 52 m_values = new Object[m_capacity]; 53 } 54 55 public int size() { 56 return m_size; 57 } 58 59 public boolean isEmpty() { 60 return (m_size == 0); 61 } 62 63 public Collection values() 64 { 65 throw new UnsupportedOperationException( 66 "SimpleMapImpl.values() not implemented!"); 67 } 68 69 public Set keySet() 70 { 71 HashSet s = new HashSet(size()); 72 Object k; 73 for (int i=0; i<m_size; i++) { 74 k = m_keys[i]; 75 if (k == nullKey) 76 s.add(null); 77 else 78 s.add(k); 79 } //for 80 return s; 81 } // keySet 82 83 public void clear() 84 { 85 for (int i=0; i<m_size; i++) { 86 m_keys[i] = null; 87 m_values[i] = null; 88 } // for 89 m_size =0; 90 } // clear 91 92 public boolean containsKey(Object key) { 93 return (getPostionByKey(key) != -1); 94 }// containsKey 95 96 public boolean containsValue(Object value) { 97 return (getPostionByValue(value) != -1); 98 } 99 100 public Object get(Object key) { 101 int pos = getPostionByKey(key); 102 return (pos == -1) ? null : m_values[pos]; 103 } // get 104 105 public Object put(Object key, Object value) 106 { 107 int pos = getPostionByKey(key); 108 if (pos >= 0) { 109 Object oldVal = m_values[pos]; 110 m_values[pos] = value; 111 return oldVal; 112 } 113 114 if (m_size == m_capacity) 115 increaseCapacity(); 116 117 if (g_akey == null) 118 theKeysHere.put(key, key); 119 else 120 key = g_akey; 121 m_keys[m_size] = key; 122 m_values[m_size] = value; 123 m_size++; 124 return null; 125 } // put 126 127 public Object remove(Object key) 128 { 129 int pos = getSubsumeKey((key==null)?nullKey:key);//getPostionByKey(key); 130 if (pos == -1) 131 return null; 132 133 Object oldVal = m_values[pos]; 134 m_size--; 135 if (m_size != 0) 136 { 137 m_keys[pos] = m_keys[m_size]; 138 m_values[pos] = m_values[m_size]; 139 } 140 m_keys[m_size] = null; 141 m_values[m_size] = null; 142 143 return oldVal; 144 } // remove 145 146 public void putAll(Map t) 147 { 148 if (t == null) { 149 throw new UnsupportedOperationException( 150 "SimpleMapImpl.putAll argument is null"); 151 } 152 153 if (t instanceof SimpleMapImpl) { 154 SimpleMapImpl sfm = (SimpleMapImpl)t; 155 Object key; 156 for (int i=0; i<sfm.m_size; i++) { 157 key = sfm.m_keys[i]; 158 put(key, sfm.m_values[i]); 159 } //for 160 } else { 161 Iterator entries = t.entrySet().iterator(); 162 Map.Entry e; 163 while (entries.hasNext()) { 164 e = (Map.Entry)entries.next(); 165 put(e.getKey(), e.getValue()); 166 } // while 167 } // if 168 } // putAll 169 170 transient Object g_akey = null; 171 private int getPostionByKey(Object key) { 172 if (key == null) 173 key = nullKey; 174 g_akey = theKeysHere.get(key); 175 if (g_akey == null) 176 return -1; 177 178 for (int i=0; i<m_size; i++) { 179 if (g_akey.equals(m_keys[i])) 180 return i; 181 } // for 182 return -1; 183 } // getPostionByKey 184 185 protected int getSubsumeKey(Object key) { 186 for (int i=0; i<m_size; i++) { 187 if (key == m_keys[i]) 188 return i; 189 } // for 190 return -1; 191 } // getPostionByKey 192 193 private int getPostionByValue(Object value) { 194 Object av; 195 for (int i=0; i<m_size; i++) { 196 av = m_values[i]; 197 if (value == null) { 198 if (av == null) 199 return i; 200 } 201 else 202 if (value.equals(av)) 203 return i; 204 } // for 205 206 return -1; 207 } // getPostionByValue 208 209 // Modification Operations 210 private void increaseCapacity() 211 { 212 int m_oldCapacity = m_capacity; 213 m_capacity *= 2; 214 Object m_oldKeys[] = m_keys; 215 m_keys = new Object[m_capacity]; 216 217 Object m_oldValues[] = m_values; 218 m_values = new Object[m_capacity]; 219 220 System.arraycopy(m_oldKeys, 0, m_keys, 0, m_oldCapacity); 221 System.arraycopy(m_oldValues, 0, m_values, 0, m_oldCapacity); 222 } // increaseCapacity 223 224 /** 225 * Auxiliary classes needed for the support of entrySet() method 226 */ 227 private static class Entry implements Map.Entry { 228 int hash; 229 Object key; 230 Object value; 231 232 Entry(int hash, Object key, Object value) { 233 this.hash = hash; 234 this.key = key; 235 this.value = value; 236 } 237 238 protected Object clone() { 239 return new Entry(hash, key, value); 240 } 241 242 public Object getKey() { 243 return key; 244 } 245 246 public Object getValue() { 247 return value; 248 } 249 250 public Object setValue(Object value) { 251 Object oldValue = this.value; 252 this.value = value; 253 return oldValue; 254 } 255 256 public boolean equals(Object o) { 257 if (!(o instanceof Map.Entry)) 258 return false; 259 Map.Entry e = (Map.Entry)o; 260 261 return (key==null ? e.getKey()==null : key.equals(e.getKey())) && 262 (value==null ? e.getValue()==null : value.equals(e.getValue())); 263 } 264 265 public int hashCode() { 266 return hash ^ (key==null ? 0 : key.hashCode()); 267 } 268 269 public String toString() { 270 return key+"="+value; 271 } 272 } // Entry 273 274 275 public Set entrySet() { 276 HashSet s = new HashSet(size()); 277 Object v, k; 278 for (int i=0; i<m_size; i++) { 279 k = m_keys[i]; 280 s.add(new Entry(k.hashCode(), ((k==nullKey)?null:k), m_values[i])); 281 } //for 282 return s; 283 } // entrySet 284 285 // Comparison and hashing 286 287 public boolean equals(Object o) { 288 if (!(o instanceof Map)) { 289 return false; 290 } 291 292 Map m = (Map)o; 293 if (m.size() != m_size) { 294 return false; 295 } 296 297 Object v, k; 298 for (int i=0; i<m_size; i++) { 299 k = m_keys[i]; 300 v = m.get(k); 301 if (v==null) { 302 if (m_values[i]!=null) 303 return false; 304 } 305 else if (!v.equals(m_values[i])){ 306 return false; 307 } 308 } // for 309 310 return true; 311 } // equals 312 313 /* 314 public int hashCode() { 315 int hash=0; 316 Object key; 317 for (int i=0; i<m_capacity; i++) { 318 key = m_keys[i]; 319 if (key == null) 320 continue; 321 HashMap hm; 322 hash += m_keys[i].hashCode(); 323 hash += m_values[i].hashCode(); 324 } // for 325 326 return hash; 327 } // hashCode 328 */ 329 330 public int hashCode() { 331 int h = 0; 332 Iterator i = entrySet().iterator(); 333 while (i.hasNext()) 334 h += i.next().hashCode(); 335 return h; 336 } 337 338 339 public Object clone() { 340 SimpleMapImpl newMap; 341 try { 342 newMap = (SimpleMapImpl)super.clone(); 343 } catch (CloneNotSupportedException e) { 344 throw(new InternalError(e.toString())); 345 } 346 347 newMap.m_size = m_size; 348 newMap.m_keys = new Object[m_capacity]; 349 System.arraycopy(m_keys, 0, newMap.m_keys, 0, m_capacity); 350 351 newMap.m_values = new Object[m_capacity]; 352 System.arraycopy(m_values, 0, newMap.m_values, 0, m_capacity); 353 354 return newMap; 355 } // clone 356 357 public String toString() { 358 int max = size() - 1; 359 StringBuffer buf = new StringBuffer(); 360 Iterator i = entrySet().iterator(); 361 362 buf.append("{"); 363 for (int j = 0; j <= max; j++) { 364 Entry e = (Entry) (i.next()); 365 buf.append(e.getKey() + "=" + e.getValue()); 366 if (j < max) 367 buf.append(", "); 368 } 369 buf.append("}"); 370 return buf.toString(); 371 } 372 373 374 /** Freeze the serialization UID. */ 375 static final long serialVersionUID = -6747241616127229116L; 376 377 /** the Object instance that will represent the NULL keys in the map */ 378 transient static Object nullKey = new Object(); 379 transient public static HashMap theKeysHere = new HashMap(); 380 static { 381 theKeysHere.put(nullKey, nullKey); 382 } 383 384 /** the static keys colleaction */ 385 } //SimpleMapImpl 386
|
SimpleMapImpl |
|