001: package com.tagtraum.framework.util;
002:
003: import java.util.*;
004:
005: /**
006: * Map that maintains insertion order.
007: * Does not properly deal with null keys.
008: *
009: * @version 1.1beta1, Revision: $id: $
010: * @author <a href="mailto:hs@tagtraum.com">Hendrik Schreiber</a>
011: */
012: public class OrderedMap {
013:
014: private Map map;
015: private List list;
016:
017: public OrderedMap() {
018: this .map = new HashMap();
019: this .list = new ArrayList();
020: }
021:
022: public boolean containsKey(Object key) {
023: return map.containsKey(key);
024: }
025:
026: /**
027: * This method does NOT return a set that maintains the insertion order.
028: */
029: public Set keySet() {
030: return Collections.unmodifiableSet(map.keySet());
031: }
032:
033: public Object put(Object key, Object value) {
034: Object oldValue = map.put(key, value);
035: if (oldValue != null) {
036: // find the right element
037: Entry oldEntry = new Entry(key, oldValue);
038: int i = list.indexOf(oldEntry);
039: Entry e = (Entry) list.get(i);
040: e.setIntValue(value);
041: } else {
042: list.add(new Entry(key, value));
043: }
044: return oldValue;
045: }
046:
047: public Object remove(Object key) {
048: Object oldValue = map.remove(key);
049: if (oldValue != null)
050: list.remove(new Entry(key, oldValue));
051: return oldValue;
052: }
053:
054: public Object get(Object key) {
055: return map.get(key);
056: }
057:
058: public void clear() {
059: map.clear();
060: list.clear();
061: }
062:
063: public boolean isEmpty() {
064: return map.isEmpty();
065: }
066:
067: public List entryList() {
068: return Collections.unmodifiableList(list);
069: }
070:
071: public int size() {
072: return map.size();
073: }
074:
075: private class Entry implements Map.Entry {
076: private Object key;
077: private Object value;
078:
079: public Entry(Object key, Object value) {
080: this .key = key;
081: this .value = value;
082: }
083:
084: public Object getKey() {
085: return key;
086: }
087:
088: public Object getValue() {
089: return value;
090: }
091:
092: void setIntValue(Object value) {
093: this .value = value;
094: }
095:
096: public Object setValue(Object value) {
097: throw new UnsupportedOperationException();
098: }
099:
100: public boolean equals(Object o) {
101: if (!(o instanceof Map.Entry))
102: return false;
103: Map.Entry e = (Map.Entry) o;
104: Object k1 = getKey();
105: Object k2 = e.getKey();
106: if (k1 == k2 || (k1 != null && k1.equals(k2))) {
107: Object v1 = getValue();
108: Object v2 = e.getValue();
109: if (v1 == v2 || (v1 != null && v1.equals(v2)))
110: return true;
111: }
112: return false;
113: }
114:
115: public int hashCode() {
116: return (key.hashCode())
117: ^ (value == null ? 0 : value.hashCode());
118: }
119:
120: public String toString() {
121: return getKey() + "=" + getValue();
122: }
123: }
124:
125: }
|