1 52 53 package com.go.trove.util; 54 55 import java.util.*; 56 57 67 public class UsageMap extends AbstractMap implements java.io.Serializable { 68 private Map mRecentMap; 69 private boolean mReverse; 70 71 private Entry mMostRecent; 72 private Entry mLeastRecent; 73 74 private transient Set mEntrySet; 75 76 79 public UsageMap() { 80 this(new HashMap()); 81 } 82 83 86 public UsageMap(Map backingMap) { 87 mRecentMap = backingMap; 88 } 89 90 96 public void setReverseOrder(boolean reverse) { 97 mReverse = reverse; 98 } 99 100 104 public Object firstKey() throws NoSuchElementException { 105 Entry first = (mReverse) ? mLeastRecent : mMostRecent; 106 if (first != null) { 107 return first.mKey; 108 } 109 else if (mRecentMap.size() == 0) { 110 throw new NoSuchElementException(); 111 } 112 else { 113 return null; 114 } 115 } 116 117 121 public Object lastKey() throws NoSuchElementException { 122 Entry last = (mReverse) ? mMostRecent : mLeastRecent; 123 if (last != null) { 124 return last.mKey; 125 } 126 else if (mRecentMap.size() == 0) { 127 throw new NoSuchElementException(); 128 } 129 else { 130 return null; 131 } 132 } 133 134 public int size() { 135 return mRecentMap.size(); 136 } 137 138 public boolean isEmpty() { 139 return mRecentMap.isEmpty(); 140 } 141 142 public boolean containsKey(Object key) { 143 return mRecentMap.containsKey(key); 144 } 145 146 public Object get(Object key) { 147 Entry e = (Entry)mRecentMap.get(key); 148 return (e == null) ? null : e.mValue; 149 } 150 151 public Object put(Object key, Object value) { 152 Entry e = (Entry)mRecentMap.get(key); 153 Object old; 154 155 if (e == null) { 156 old = null; 157 e = new Entry(key, value); 158 mRecentMap.put(key, e); 159 } 160 else { 161 old = e.mValue; 162 e.mValue = value; 163 164 if (e == mMostRecent) { 165 return old; 166 } 167 168 if (e.mPrev == null) { 170 mMostRecent = e.mNext; 171 } 172 else { 173 e.mPrev.mNext = e.mNext; 174 } 175 if (e.mNext == null) { 176 mLeastRecent = e.mPrev; 177 } 178 else { 179 e.mNext.mPrev = e.mPrev; 180 } 181 e.mPrev = null; 182 } 183 184 if (mMostRecent == null) { 185 mMostRecent = e; 186 } 187 else { 188 e.mNext = mMostRecent; 189 mMostRecent.mPrev = e; 190 mMostRecent = e; 191 } 192 193 if (mLeastRecent == null) { 194 mLeastRecent = e; 195 } 196 197 return old; 198 } 199 200 public Object remove(Object key) { 201 Entry e = (Entry)mRecentMap.remove(key); 202 203 if (e == null) { 204 return null; 205 } 206 else { 207 if (e.mPrev == null) { 209 mMostRecent = e.mNext; 210 } 211 else { 212 e.mPrev.mNext = e.mNext; 213 } 214 if (e.mNext == null) { 215 mLeastRecent = e.mPrev; 216 } 217 else { 218 e.mNext.mPrev = e.mPrev; 219 } 220 221 return e.mValue; 222 } 223 } 224 225 public void putAll(Map map) { 226 Iterator it = map.entrySet().iterator(); 227 while (it.hasNext()) { 228 Map.Entry entry = (Map.Entry)it.next(); 229 mRecentMap.put(entry.getKey(), entry.getValue()); 230 } 231 } 232 233 public void clear() { 234 mRecentMap.clear(); 235 mMostRecent = null; 236 mLeastRecent = null; 237 } 238 239 public Set entrySet() { 240 if (mEntrySet != null) { 241 return mEntrySet; 242 } 243 244 mEntrySet = new AbstractSet() { 245 public Iterator iterator() { 246 if (mReverse) { 247 return new Iterator() { 248 private Entry mPrev = mLeastRecent; 249 private Entry mLast = null; 250 251 public boolean hasNext() { 252 return mPrev != null; 253 } 254 255 public Object next() { 256 if ((mLast = mPrev) == null) { 257 throw new NoSuchElementException(); 258 } 259 else { 260 mPrev = mPrev.mPrev; 261 return mLast; 262 } 263 } 264 265 public void remove() { 266 if (mLast == null) { 267 throw new IllegalStateException (); 268 } 269 else { 270 UsageMap.this.remove(mLast.mKey); 271 mLast = null; 272 } 273 } 274 }; 275 } 276 else { 277 return new Iterator() { 278 private Entry mNext = mMostRecent; 279 private Entry mLast = null; 280 281 public boolean hasNext() { 282 return mNext != null; 283 } 284 285 public Object next() { 286 if ((mLast = mNext) == null) { 287 throw new NoSuchElementException(); 288 } 289 else { 290 mNext = mNext.mNext; 291 return mLast; 292 } 293 } 294 295 public void remove() { 296 if (mLast == null) { 297 throw new IllegalStateException (); 298 } 299 else { 300 UsageMap.this.remove(mLast.mKey); 301 mLast = null; 302 } 303 } 304 }; 305 } 306 } 307 308 public int size() { 309 return mRecentMap.size(); 310 } 311 312 public boolean isEmpty() { 313 return mRecentMap.isEmpty(); 314 } 315 316 public boolean contains(Object obj) { 317 if (!(obj instanceof Map.Entry)) { 318 return false; 319 } 320 Entry e = (Entry)mRecentMap.get(((Map.Entry)obj).getKey()); 321 return e != null && e.equals(obj); 322 } 323 324 public boolean remove(Object obj) { 325 if (!(obj instanceof Map.Entry)) { 326 return false; 327 } 328 if (contains(obj)) { 329 UsageMap.this.remove(((Map.Entry)obj).getKey()); 330 return true; 331 } 332 else { 333 return false; 334 } 335 } 336 337 public void clear() { 338 UsageMap.this.clear(); 339 } 340 }; 341 342 return mEntrySet; 343 } 344 345 private static class Entry extends AbstractMapEntry 346 implements java.io.Serializable 347 { 348 public Entry mPrev; 349 public Entry mNext; 350 public Object mKey; 351 public Object mValue; 352 353 public Entry(Object key, Object value) { 354 mKey = key; 355 mValue = value; 356 } 357 358 public Object getKey() { 359 return mKey; 360 } 361 362 public Object getValue() { 363 return mValue; 364 } 365 366 public Object setValue(Object value) { 367 Object old = mValue; 368 mValue = value; 369 return old; 370 } 371 } 372 } 373 | Popular Tags |