1 16 package org.apache.commons.collections.map; 17 18 import java.io.IOException ; 19 import java.io.ObjectInputStream ; 20 import java.io.ObjectOutputStream ; 21 import java.io.Serializable ; 22 import java.util.AbstractCollection ; 23 import java.util.AbstractSet ; 24 import java.util.ArrayList ; 25 import java.util.Collection ; 26 import java.util.HashMap ; 27 import java.util.Iterator ; 28 import java.util.List ; 29 import java.util.ListIterator ; 30 import java.util.Map ; 31 import java.util.NoSuchElementException ; 32 import java.util.Set ; 33 34 import org.apache.commons.collections.MapIterator; 35 import org.apache.commons.collections.OrderedMap; 36 import org.apache.commons.collections.OrderedMapIterator; 37 import org.apache.commons.collections.ResettableIterator; 38 import org.apache.commons.collections.iterators.AbstractIteratorDecorator; 39 import org.apache.commons.collections.keyvalue.AbstractMapEntry; 40 import org.apache.commons.collections.list.UnmodifiableList; 41 42 63 public class ListOrderedMap 64 extends AbstractMapDecorator 65 implements OrderedMap, Serializable { 66 67 68 private static final long serialVersionUID = 2728177751851003750L; 69 70 71 protected final List insertOrder = new ArrayList (); 72 73 81 public static OrderedMap decorate(Map map) { 82 return new ListOrderedMap(map); 83 } 84 85 92 public ListOrderedMap() { 93 this(new HashMap ()); 94 } 95 96 102 protected ListOrderedMap(Map map) { 103 super(map); 104 insertOrder.addAll(getMap().keySet()); 105 } 106 107 115 private void writeObject(ObjectOutputStream out) throws IOException { 116 out.defaultWriteObject(); 117 out.writeObject(map); 118 } 119 120 128 private void readObject(ObjectInputStream in) throws IOException , ClassNotFoundException { 129 in.defaultReadObject(); 130 map = (Map ) in.readObject(); 131 } 132 133 public MapIterator mapIterator() { 136 return orderedMapIterator(); 137 } 138 139 public OrderedMapIterator orderedMapIterator() { 140 return new ListOrderedMapIterator(this); 141 } 142 143 149 public Object firstKey() { 150 if (size() == 0) { 151 throw new NoSuchElementException ("Map is empty"); 152 } 153 return insertOrder.get(0); 154 } 155 156 162 public Object lastKey() { 163 if (size() == 0) { 164 throw new NoSuchElementException ("Map is empty"); 165 } 166 return insertOrder.get(size() - 1); 167 } 168 169 176 public Object nextKey(Object key) { 177 int index = insertOrder.indexOf(key); 178 if (index >= 0 && index < size() - 1) { 179 return insertOrder.get(index + 1); 180 } 181 return null; 182 } 183 184 191 public Object previousKey(Object key) { 192 int index = insertOrder.indexOf(key); 193 if (index > 0) { 194 return insertOrder.get(index - 1); 195 } 196 return null; 197 } 198 199 public Object put(Object key, Object value) { 201 if (getMap().containsKey(key)) { 202 return getMap().put(key, value); 204 } else { 205 Object result = getMap().put(key, value); 207 insertOrder.add(key); 208 return result; 209 } 210 } 211 212 public void putAll(Map map) { 213 for (Iterator it = map.entrySet().iterator(); it.hasNext();) { 214 Map.Entry entry = (Map.Entry ) it.next(); 215 put(entry.getKey(), entry.getValue()); 216 } 217 } 218 219 public Object remove(Object key) { 220 Object result = getMap().remove(key); 221 insertOrder.remove(key); 222 return result; 223 } 224 225 public void clear() { 226 getMap().clear(); 227 insertOrder.clear(); 228 } 229 230 public Set keySet() { 232 return new KeySetView(this); 233 } 234 235 public Collection values() { 236 return new ValuesView(this); 237 } 238 239 public Set entrySet() { 240 return new EntrySetView(this, this.insertOrder); 241 } 242 243 249 public String toString() { 250 if (isEmpty()) { 251 return "{}"; 252 } 253 StringBuffer buf = new StringBuffer (); 254 buf.append('{'); 255 boolean first = true; 256 Iterator it = entrySet().iterator(); 257 while (it.hasNext()) { 258 Map.Entry entry = (Map.Entry ) it.next(); 259 Object key = entry.getKey(); 260 Object value = entry.getValue(); 261 if (first) { 262 first = false; 263 } else { 264 buf.append(", "); 265 } 266 buf.append(key == this ? "(this Map)" : key); 267 buf.append('='); 268 buf.append(value == this ? "(this Map)" : value); 269 } 270 buf.append('}'); 271 return buf.toString(); 272 } 273 274 282 public Object get(int index) { 283 return insertOrder.get(index); 284 } 285 286 293 public Object getValue(int index) { 294 return get(insertOrder.get(index)); 295 } 296 297 303 public int indexOf(Object key) { 304 return insertOrder.indexOf(key); 305 } 306 307 315 public Object remove(int index) { 316 return remove(get(index)); 317 } 318 319 334 public List asList() { 335 return UnmodifiableList.decorate(insertOrder); 336 } 337 338 static class ValuesView extends AbstractCollection { 340 private final ListOrderedMap parent; 341 342 ValuesView(ListOrderedMap parent) { 343 super(); 344 this.parent = parent; 345 } 346 347 public int size() { 348 return this.parent.size(); 349 } 350 351 public boolean contains(Object value) { 352 return this.parent.containsValue(value); 353 } 354 355 public void clear() { 356 this.parent.clear(); 357 } 358 359 public Iterator iterator() { 360 return new AbstractIteratorDecorator(parent.entrySet().iterator()) { 361 public Object next() { 362 return ((Map.Entry ) iterator.next()).getValue(); 363 } 364 }; 365 } 366 } 367 368 static class KeySetView extends AbstractSet { 370 private final ListOrderedMap parent; 371 372 KeySetView(ListOrderedMap parent) { 373 super(); 374 this.parent = parent; 375 } 376 377 public int size() { 378 return this.parent.size(); 379 } 380 381 public boolean contains(Object value) { 382 return this.parent.containsKey(value); 383 } 384 385 public void clear() { 386 this.parent.clear(); 387 } 388 389 public Iterator iterator() { 390 return new AbstractIteratorDecorator(parent.entrySet().iterator()) { 391 public Object next() { 392 return ((Map.Entry ) super.next()).getKey(); 393 } 394 }; 395 } 396 } 397 398 static class EntrySetView extends AbstractSet { 400 private final ListOrderedMap parent; 401 private final List insertOrder; 402 private Set entrySet; 403 404 public EntrySetView(ListOrderedMap parent, List insertOrder) { 405 super(); 406 this.parent = parent; 407 this.insertOrder = insertOrder; 408 } 409 410 private Set getEntrySet() { 411 if (entrySet == null) { 412 entrySet = parent.getMap().entrySet(); 413 } 414 return entrySet; 415 } 416 417 public int size() { 418 return this.parent.size(); 419 } 420 public boolean isEmpty() { 421 return this.parent.isEmpty(); 422 } 423 424 public boolean contains(Object obj) { 425 return getEntrySet().contains(obj); 426 } 427 428 public boolean containsAll(Collection coll) { 429 return getEntrySet().containsAll(coll); 430 } 431 432 public boolean remove(Object obj) { 433 if (obj instanceof Map.Entry == false) { 434 return false; 435 } 436 if (getEntrySet().contains(obj)) { 437 Object key = ((Map.Entry ) obj).getKey(); 438 parent.remove(key); 439 return true; 440 } 441 return false; 442 } 443 444 public void clear() { 445 this.parent.clear(); 446 } 447 448 public boolean equals(Object obj) { 449 if (obj == this) { 450 return true; 451 } 452 return getEntrySet().equals(obj); 453 } 454 455 public int hashCode() { 456 return getEntrySet().hashCode(); 457 } 458 459 public String toString() { 460 return getEntrySet().toString(); 461 } 462 463 public Iterator iterator() { 464 return new ListOrderedIterator(parent, insertOrder); 465 } 466 } 467 468 static class ListOrderedIterator extends AbstractIteratorDecorator { 470 private final ListOrderedMap parent; 471 private Object last = null; 472 473 ListOrderedIterator(ListOrderedMap parent, List insertOrder) { 474 super(insertOrder.iterator()); 475 this.parent = parent; 476 } 477 478 public Object next() { 479 last = super.next(); 480 return new ListOrderedMapEntry(parent, last); 481 } 482 483 public void remove() { 484 super.remove(); 485 parent.getMap().remove(last); 486 } 487 } 488 489 static class ListOrderedMapEntry extends AbstractMapEntry { 491 private final ListOrderedMap parent; 492 493 ListOrderedMapEntry(ListOrderedMap parent, Object key) { 494 super(key, null); 495 this.parent = parent; 496 } 497 498 public Object getValue() { 499 return parent.get(key); 500 } 501 502 public Object setValue(Object value) { 503 return parent.getMap().put(key, value); 504 } 505 } 506 507 static class ListOrderedMapIterator implements OrderedMapIterator, ResettableIterator { 509 private final ListOrderedMap parent; 510 private ListIterator iterator; 511 private Object last = null; 512 private boolean readable = false; 513 514 ListOrderedMapIterator(ListOrderedMap parent) { 515 super(); 516 this.parent = parent; 517 this.iterator = parent.insertOrder.listIterator(); 518 } 519 520 public boolean hasNext() { 521 return iterator.hasNext(); 522 } 523 524 public Object next() { 525 last = iterator.next(); 526 readable = true; 527 return last; 528 } 529 530 public boolean hasPrevious() { 531 return iterator.hasPrevious(); 532 } 533 534 public Object previous() { 535 last = iterator.previous(); 536 readable = true; 537 return last; 538 } 539 540 public void remove() { 541 if (readable == false) { 542 throw new IllegalStateException (AbstractHashedMap.REMOVE_INVALID); 543 } 544 iterator.remove(); 545 parent.map.remove(last); 546 readable = false; 547 } 548 549 public Object getKey() { 550 if (readable == false) { 551 throw new IllegalStateException (AbstractHashedMap.GETKEY_INVALID); 552 } 553 return last; 554 } 555 556 public Object getValue() { 557 if (readable == false) { 558 throw new IllegalStateException (AbstractHashedMap.GETVALUE_INVALID); 559 } 560 return parent.get(last); 561 } 562 563 public Object setValue(Object value) { 564 if (readable == false) { 565 throw new IllegalStateException (AbstractHashedMap.SETVALUE_INVALID); 566 } 567 return parent.map.put(last, value); 568 } 569 570 public void reset() { 571 iterator = parent.insertOrder.listIterator(); 572 last = null; 573 readable = false; 574 } 575 576 public String toString() { 577 if (readable == true) { 578 return "Iterator[" + getKey() + "=" + getValue() + "]"; 579 } else { 580 return "Iterator[]"; 581 } 582 } 583 } 584 585 } 586 | Popular Tags |