Collections Java Tutorial

/*
 * Copyright 2004, 2005, 2006 Odysseus Software GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import java.util.AbstractCollection;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
 * 
 * List ordered map.
 * The iterators returned by keySet()values()
 * and entrySet() methods reflect the order in which keys have
 * been added to the map.
 *
 * @author Christoph Beck
 */
public class ListOrderedMap implements Map {
  private final Map map;
  private final List lst; 
  public static Map decorate(Map map) {
    return new ListOrderedMap(map, new ArrayList());
  }
  
  protected ListOrderedMap(Map map, List lst) {
    super();
    
    this.map = map;
    this.lst = lst;
    lst.addAll(map.keySet());
  }
    public boolean containsKey(Object key) {
        return map.containsKey(key);
    }
    public boolean containsValue(Object value) {
        return map.containsValue(value);
    }
    public Object get(Object key) {
        return map.get(key);
    }
    public boolean isEmpty() {
        return map.isEmpty();
    }
    public int size() {
        return map.size();
    }
   
    public boolean equals(Object object) {
      return object == this ? true : map.equals(object); 
    }
    public int hashCode() {
        return map.hashCode();
    }
  public Object put(Object key, Object value) {
    if (!map.containsKey(key)) {
      lst.add(key);
    }
    return map.put(key, value);
  }
  public void putAll(Map map) {
    Iterator it = map.entrySet().iterator();
    while (it.hasNext()) {
      Map.Entry entry = (Map.Entry) it.next();
      put(entry.getKey(), entry.getValue());
    }
  }
  public Object remove(Object key) {
    if (map.containsKey(key)) {
      lst.remove(key);
      return map.remove(key);
    }
    return null;
  }
  public void clear() {
    map.clear();
    lst.clear();
  }
  public Collection values() {
    return new AbstractCollection() {
      public int size() {
        return map.size();
      }
      public boolean contains(Object value) {
        return map.containsValue(value);
      }
      public void clear() {
        ListOrderedMap.this.clear();
      }
      public Iterator iterator() {
        return new Iterator() {
          Object last = null;
          Iterator keys = lst.iterator();
          public Object next() {
            return map.get(last = keys.next());
          }
          public boolean hasNext() {
            return keys.hasNext();
          }
          public void remove() {
            keys.remove();
            map.remove(last);
          }
        };
      }
    };
  }
  public Set keySet() {
    return new AbstractSet() {
      public int size() {
        return map.size();
      }
      public boolean contains(Object value) {
        return map.containsKey(value);
      }
      public void clear() {
        ListOrderedMap.this.clear();
      }
      public Iterator iterator() {
        return new Iterator() {
          Object last = null;
          Iterator keys = lst.iterator();
          public Object next() {
            return last = keys.next();
          }
          public boolean hasNext() {
            return keys.hasNext();
          }
          public void remove() {
            keys.remove();
            map.remove(last);
          }
        };
      }
    };
  }
  
  public Set entrySet() {
    return new AbstractSet() {
      Set delegate = ListOrderedMap.this.map.entrySet();
      public int size() {
        return ListOrderedMap.this.size();
      }
      public boolean contains(Object obj) {
        return delegate.contains(obj);
      }
      public boolean remove(Object obj) {
        boolean result = contains(obj);
        if (result) {
          ListOrderedMap.this.remove(((Map.Entry)obj).getKey());
        }
        return result;
      }
      public void clear() {
        ListOrderedMap.this.clear();
      }
      public boolean equals(Object obj) {
        return obj == this ? true : delegate.equals(obj);
      }
      public int hashCode() {
        return delegate.hashCode();
      }
      public String toString() {
        return delegate.toString();
      }
      public Iterator iterator() {
        return new Iterator() {
          Iterator keys = lst.iterator();
          Object last = null;
          public Object next() {
            last = keys.next();
            return new Map.Entry() {
              Object key = last;
              public Object getKey() {
                return key;
              }
              public Object getValue() {
                return map.get(key);
              }
              public Object setValue(Object value) {
                return map.put(key, value);
              }
            };
          }
          public boolean hasNext() {
            return keys.hasNext();
          }
          public void remove() {
            keys.remove();
            map.remove(last);
          }
        };
      }
    };
  }
  public String toString() {
    StringBuffer buf = new StringBuffer();
    buf.append('{');
    Iterator keys = keySet().iterator();
    while (keys.hasNext()) {
      Object key = keys.next();
      buf.append(key);
      buf.append('=');
      buf.append(get(key));
      if (keys.hasNext()) {
        buf.append(", ");
      }
    }
    buf.append('}');
    return buf.toString();
  }
}