首页

关于apache的commons-collections的SequencedHashMap实现j自定义java.lang.map接口

标签:SequencedHashMap,commons-collections,apache,自定义map     发布时间:2018-02-14   

一、前言

关于apachecommons-collections的org.apache.commons.collections.SequencedHashMap实现了基于java.lang.Map接口,并增强和补充了原有的java.util.HashMap功能,详细参考下面源码说明部分。

二、源码说明

package org.apache.commons.collections;@b@@b@import java.io.DataInput;@b@import java.io.DataOutput;@b@import java.io.Externalizable;@b@import java.io.IOException;@b@import java.io.ObjectInput;@b@import java.io.ObjectOutput;@b@import java.util.AbstractCollection;@b@import java.util.AbstractSet;@b@import java.util.ArrayList;@b@import java.util.Collection;@b@import java.util.ConcurrentModificationException;@b@import java.util.HashMap;@b@import java.util.Iterator;@b@import java.util.List;@b@import java.util.Map;@b@import java.util.Map.Entry;@b@import java.util.NoSuchElementException;@b@import java.util.Set;@b@import org.apache.commons.collections.list.UnmodifiableList;@b@@b@@b@public class SequencedHashMap@b@  implements Map, Cloneable, Externalizable@b@{@b@  private Entry sentinel;@b@  private HashMap entries;@b@  private transient long modCount;@b@  private static final int KEY = 0;@b@  private static final int VALUE = 1;@b@  private static final int ENTRY = 2;@b@  private static final int REMOVED_MASK = -2147483648;@b@  private static final long serialVersionUID = 3380552487888102930L;@b@@b@  private static final Entry createSentinel()@b@  {@b@    Entry s = new Entry(null, null);@b@    s.prev = s;@b@    s.next = s;@b@    return s;@b@  }@b@@b@  public SequencedHashMap()@b@  {@b@    this.modCount = 0L;@b@@b@    this.sentinel = createSentinel();@b@    this.entries = new HashMap();@b@  }@b@@b@  public SequencedHashMap(int initialSize)@b@  {@b@    this.modCount = 0L;@b@@b@    this.sentinel = createSentinel();@b@    this.entries = new HashMap(initialSize);@b@  }@b@@b@  public SequencedHashMap(int initialSize, float loadFactor)@b@  {@b@    this.modCount = 0L;@b@@b@    this.sentinel = createSentinel();@b@    this.entries = new HashMap(initialSize, loadFactor);@b@  }@b@@b@  public SequencedHashMap(Map m)@b@  {@b@    putAll(m);@b@  }@b@@b@  private void removeEntry(Entry entry)@b@  {@b@    entry.next.prev = entry.prev;@b@    entry.prev.next = entry.next;@b@  }@b@@b@  private void insertEntry(Entry entry)@b@  {@b@    entry.next = this.sentinel;@b@    entry.prev = this.sentinel.prev;@b@    this.sentinel.prev.next = entry;@b@    this.sentinel.prev = entry;@b@  }@b@@b@  public int size()@b@  {@b@    return this.entries.size();@b@  }@b@@b@  public boolean isEmpty()@b@  {@b@    return (this.sentinel.next == this.sentinel);@b@  }@b@@b@  public boolean containsKey(Object key)@b@  {@b@    return this.entries.containsKey(key);@b@  }@b@@b@  public boolean containsValue(Object value)@b@  {@b@    Entry pos;@b@    if (value == null)@b@      for (pos = this.sentinel.next; pos != this.sentinel; pos = pos.next)@b@        if (pos.getValue() == null)@b@          return true;@b@@b@    else@b@      for (pos = this.sentinel.next; pos != this.sentinel; pos = pos.next)@b@        if (value.equals(pos.getValue()))@b@          return true;@b@@b@@b@    return false;@b@  }@b@@b@  public Object get(Object o)@b@  {@b@    Entry entry = (Entry)this.entries.get(o);@b@    if (entry == null)@b@      return null;@b@@b@    return entry.getValue();@b@  }@b@@b@  public Map.Entry getFirst()@b@  {@b@    return ((isEmpty()) ? null : this.sentinel.next);@b@  }@b@@b@  public Object getFirstKey()@b@  {@b@    return this.sentinel.next.getKey();@b@  }@b@@b@  public Object getFirstValue()@b@  {@b@    return this.sentinel.next.getValue();@b@  }@b@@b@  public Map.Entry getLast()@b@  {@b@    return ((isEmpty()) ? null : this.sentinel.prev);@b@  }@b@@b@  public Object getLastKey()@b@  {@b@    return this.sentinel.prev.getKey();@b@  }@b@@b@  public Object getLastValue()@b@  {@b@    return this.sentinel.prev.getValue();@b@  }@b@@b@  public Object put(Object key, Object value)@b@  {@b@    this.modCount += 1L;@b@@b@    Object oldValue = null;@b@@b@    Entry e = (Entry)this.entries.get(key);@b@@b@    if (e != null)@b@    {@b@      removeEntry(e);@b@@b@      oldValue = e.setValue(value);@b@    }@b@    else@b@    {@b@      e = new Entry(key, value);@b@      this.entries.put(key, e);@b@    }@b@@b@    insertEntry(e);@b@@b@    return oldValue;@b@  }@b@@b@  public Object remove(Object key)@b@  {@b@    Entry e = removeImpl(key);@b@    return ((e == null) ? null : e.getValue());@b@  }@b@@b@  private Entry removeImpl(Object key)@b@  {@b@    Entry e = (Entry)this.entries.remove(key);@b@    if (e == null)@b@      return null;@b@    this.modCount += 1L;@b@    removeEntry(e);@b@    return e;@b@  }@b@@b@  public void putAll(Map t)@b@  {@b@    Iterator iter = t.entrySet().iterator();@b@    while (iter.hasNext()) {@b@      Map.Entry entry = (Map.Entry)iter.next();@b@      put(entry.getKey(), entry.getValue());@b@    }@b@  }@b@@b@  public void clear()@b@  {@b@    this.modCount += 1L;@b@@b@    this.entries.clear();@b@@b@    this.sentinel.next = this.sentinel;@b@    this.sentinel.prev = this.sentinel;@b@  }@b@@b@  public boolean equals(Object obj)@b@  {@b@    if (obj == null)@b@      return false;@b@    if (obj == this)@b@      return true;@b@@b@    if (!(obj instanceof Externalizable))@b@      return false;@b@@b@    return entrySet().equals(((Externalizable)obj).entrySet());@b@  }@b@@b@  public int hashCode()@b@  {@b@    return entrySet().hashCode();@b@  }@b@@b@  public String toString()@b@  {@b@    StringBuffer buf = new StringBuffer();@b@    buf.append('[');@b@    for (Entry pos = this.sentinel.next; pos != this.sentinel; pos = pos.next) {@b@      buf.append(pos.getKey());@b@      buf.append('=');@b@      buf.append(pos.getValue());@b@      if (pos.next != this.sentinel)@b@        buf.append(',');@b@    }@b@@b@    buf.append(']');@b@@b@    return buf.toString();@b@  }@b@@b@  public Set keySet()@b@  {@b@    return new AbstractSet(this) {@b@      private final SequencedHashMap this$0;@b@@b@      public Iterator iterator() {@b@        return new SequencedHashMap.OrderedIterator(this.this$0, 0); }@b@@b@      public boolean remove() {@b@        SequencedHashMap.Entry e = SequencedHashMap.access$000(this.this$0, o);@b@        return (e != null);@b@      }@b@@b@      public void clear()@b@      {@b@        this.this$0.clear(); }@b@@b@      public int size() {@b@        return this.this$0.size(); }@b@@b@      public boolean isEmpty() {@b@        return this.this$0.isEmpty(); }@b@@b@      public boolean contains() {@b@        return this.this$0.containsKey(o);@b@      }@b@    };@b@  }@b@@b@  public Collection values()@b@  {@b@    return new AbstractCollection(this) {@b@      private final SequencedHashMap this$0;@b@@b@      public Iterator iterator() { return new SequencedHashMap.OrderedIterator(this.this$0, 1);@b@      }@b@@b@      public boolean remove()@b@      {@b@        SequencedHashMap.Entry pos;@b@        if (value == null)@b@          for (pos = SequencedHashMap.access$100(this.this$0).next; pos != SequencedHashMap.access$100(this.this$0); pos = pos.next)@b@            if (pos.getValue() == null) {@b@              SequencedHashMap.access$000(this.this$0, pos.getKey());@b@              return true;@b@            }@b@@b@        else@b@          for (pos = SequencedHashMap.access$100(this.this$0).next; pos != SequencedHashMap.access$100(this.this$0); pos = pos.next)@b@            if (value.equals(pos.getValue())) {@b@              SequencedHashMap.access$000(this.this$0, pos.getKey());@b@              return true;@b@            }@b@@b@@b@@b@        return false;@b@      }@b@@b@      public void clear()@b@      {@b@        this.this$0.clear(); }@b@@b@      public int size() {@b@        return this.this$0.size(); }@b@@b@      public boolean isEmpty() {@b@        return this.this$0.isEmpty(); }@b@@b@      public boolean contains() {@b@        return this.this$0.containsValue(o);@b@      }@b@    };@b@  }@b@@b@  public Set entrySet()@b@  {@b@    return new AbstractSet(this) {@b@      private final SequencedHashMap this$0;@b@@b@      private SequencedHashMap.Entry findEntry() { if (o == null)@b@          return null;@b@        if (!(o instanceof Map.Entry))@b@          return null;@b@@b@        Map.Entry e = (Map.Entry)o;@b@        SequencedHashMap.Entry entry = (SequencedHashMap.Entry)SequencedHashMap.access$200(this.this$0).get(e.getKey());@b@        if ((entry != null) && (entry.equals(e)))@b@          return entry;@b@@b@        return null;@b@      }@b@@b@      public Iterator iterator()@b@      {@b@        return new SequencedHashMap.OrderedIterator(this.this$0, 2); }@b@@b@      public boolean remove() {@b@        SequencedHashMap.Entry e = findEntry(o);@b@        if (e == null)@b@          return false;@b@@b@        return (SequencedHashMap.access$000(this.this$0, e.getKey()) != null);@b@      }@b@@b@      public void clear()@b@      {@b@        this.this$0.clear(); }@b@@b@      public int size() {@b@        return this.this$0.size(); }@b@@b@      public boolean isEmpty() {@b@        return this.this$0.isEmpty(); }@b@@b@      public boolean contains() {@b@        return (findEntry(o) != null);@b@      }@b@    };@b@  }@b@@b@  public Object clone()@b@    throws CloneNotSupportedException@b@  {@b@    SequencedHashMap map = (SequencedHashMap)super.clone();@b@@b@    map.sentinel = createSentinel();@b@@b@    map.entries = new HashMap();@b@@b@    map.putAll(this);@b@@b@    return map;@b@  }@b@@b@  private Map.Entry getEntry(int index)@b@  {@b@    Entry pos = this.sentinel;@b@@b@    if (index < 0) {@b@      throw new ArrayIndexOutOfBoundsException(index + " < 0");@b@    }@b@@b@    int i = -1;@b@    while ((i < index - 1) && (pos.next != this.sentinel)) {@b@      ++i;@b@      pos = pos.next;@b@    }@b@@b@    if (pos.next == this.sentinel) {@b@      throw new ArrayIndexOutOfBoundsException(index + " >= " + (i + 1));@b@    }@b@@b@    return pos.next;@b@  }@b@@b@  public Object get(int index)@b@  {@b@    return getEntry(index).getKey();@b@  }@b@@b@  public Object getValue(int index)@b@  {@b@    return getEntry(index).getValue();@b@  }@b@@b@  public int indexOf(Object key)@b@  {@b@    Entry e = (Entry)this.entries.get(key);@b@    if (e == null)@b@      return -1;@b@@b@    int pos = 0;@b@    while (e.prev != this.sentinel) {@b@      ++pos;@b@      e = e.prev;@b@    }@b@    return pos;@b@  }@b@@b@  public Iterator iterator()@b@  {@b@    return keySet().iterator();@b@  }@b@@b@  public int lastIndexOf(Object key)@b@  {@b@    return indexOf(key);@b@  }@b@@b@  public List sequence()@b@  {@b@    List l = new ArrayList(size());@b@    Iterator iter = keySet().iterator();@b@    while (iter.hasNext()) {@b@      l.add(iter.next());@b@    }@b@@b@    return UnmodifiableList.decorate(l);@b@  }@b@@b@  public Object remove(int index)@b@  {@b@    return remove(get(index));@b@  }@b@@b@  public void readExternal(ObjectInput in)@b@    throws IOException, ClassNotFoundException@b@  {@b@    int size = in.readInt();@b@    for (int i = 0; i < size; ++i) {@b@      Object key = in.readObject();@b@      Object value = in.readObject();@b@      put(key, value);@b@    }@b@  }@b@@b@  public void writeExternal(ObjectOutput out)@b@    throws IOException@b@  {@b@    out.writeInt(size());@b@    for (Entry pos = this.sentinel.next; pos != this.sentinel; pos = pos.next) {@b@      out.writeObject(pos.getKey());@b@      out.writeObject(pos.getValue());@b@    }@b@  }@b@@b@  static Entry access$000(SequencedHashMap x0, Object x1)@b@  {@b@    return x0.removeImpl(x1); } @b@  static Entry access$100(SequencedHashMap x0) { return x0.sentinel; } @b@  static HashMap access$200(SequencedHashMap x0) { return x0.entries; } @b@  static long access$300(SequencedHashMap x0) { return x0.modCount;@b@  }@b@@b@  private class OrderedIterator@b@    implements Iterator@b@  {@b@    private int returnType;@b@    private SequencedHashMap.Entry pos;@b@    private transient long expectedModCount;@b@    private final SequencedHashMap this$0;@b@@b@    public OrderedIterator(, int returnType)@b@    {@b@      this.this$0 = this$0;@b@@b@      this.pos = SequencedHashMap.access$100(this.this$0);@b@@b@      this.expectedModCount = SequencedHashMap.access$300(this.this$0);@b@@b@      this.returnType = (returnType | 0x80000000);@b@    }@b@@b@    public boolean hasNext()@b@    {@b@      return (this.pos.next != SequencedHashMap.access$100(this.this$0));@b@    }@b@@b@    public Object next()@b@    {@b@      if (SequencedHashMap.access$300(this.this$0) != this.expectedModCount)@b@        throw new ConcurrentModificationException();@b@@b@      if (this.pos.next == SequencedHashMap.access$100(this.this$0)) {@b@        throw new NoSuchElementException();@b@      }@b@@b@      this.returnType &= 2147483647;@b@@b@      this.pos = this.pos.next;@b@      switch (this.returnType)@b@      {@b@      case 0:@b@        return this.pos.getKey();@b@      case 1:@b@        return this.pos.getValue();@b@      case 2:@b@        return this.pos;@b@      }@b@@b@      throw new Error("bad iterator type: " + this.returnType);@b@    }@b@@b@    public void remove()@b@    {@b@      if ((this.returnType & 0x80000000) != 0)@b@        throw new IllegalStateException("remove() must follow next()");@b@@b@      if (SequencedHashMap.access$300(this.this$0) != this.expectedModCount) {@b@        throw new ConcurrentModificationException();@b@      }@b@@b@      SequencedHashMap.access$000(this.this$0, this.pos.getKey());@b@@b@      this.expectedModCount += 1L;@b@@b@      this.returnType |= -2147483648;@b@    }@b@  }@b@@b@  private static class Entry@b@    implements Map.Entry, KeyValue@b@  {@b@    private final Object key;@b@    private Object value;@b@    Entry next = null;@b@    Entry prev = null;@b@@b@    public Entry(Object key, Object value)@b@    {@b@      this.key = key;@b@      this.value = value;@b@    }@b@@b@    public Object getKey()@b@    {@b@      return this.key;@b@    }@b@@b@    public Object getValue()@b@    {@b@      return this.value;@b@    }@b@@b@    public Object setValue(Object value)@b@    {@b@      Object oldValue = this.value;@b@      this.value = value;@b@      return oldValue;@b@    }@b@@b@    public int hashCode()@b@    {@b@      return (((getKey() == null) ? 0 : getKey().hashCode()) ^ ((getValue() == null) ? 0 : getValue().hashCode()));@b@    }@b@@b@    public boolean equals(Object obj) {@b@      if (obj == null)@b@        return false;@b@      if (obj == this)@b@        return true;@b@      if (!(obj instanceof KeyValue))@b@        return false;@b@@b@      Map.Entry other = (KeyValue)obj;@b@@b@      if (((getKey() == null) ? false : (other.getKey() == null) ? true : getKey().equals(other.getKey())));@b@      return (((getValue() == null) ? false : (other.getValue() == null) ? true : getValue().equals(other.getValue())));@b@    }@b@@b@    public String toString()@b@    {@b@      return "[" + getKey() + "=" + getValue() + "]";@b@    }@b@  }@b@}

2.UnmodifiableList

package org.apache.commons.collections.list;@b@@b@import java.util.Collection;@b@import java.util.Iterator;@b@import java.util.List;@b@import java.util.ListIterator;@b@import org.apache.commons.collections.Unmodifiable;@b@import org.apache.commons.collections.collection.AbstractCollectionDecorator;@b@import org.apache.commons.collections.iterators.UnmodifiableIterator;@b@import org.apache.commons.collections.iterators.UnmodifiableListIterator;@b@@b@public final class UnmodifiableList extends AbstractSerializableListDecorator@b@  implements Unmodifiable@b@{@b@  private static final long serialVersionUID = 6595182819922443652L;@b@@b@  public static List decorate(List list)@b@  {@b@    if (list instanceof Unmodifiable)@b@      return list;@b@@b@    return new UnmodifiableList(list);@b@  }@b@@b@  private UnmodifiableList(List list)@b@  {@b@    super(list);@b@  }@b@@b@  public Iterator iterator()@b@  {@b@    return UnmodifiableIterator.decorate(getCollection().iterator());@b@  }@b@@b@  public boolean add(Object object) {@b@    throw new UnsupportedOperationException();@b@  }@b@@b@  public boolean addAll(Collection coll) {@b@    throw new UnsupportedOperationException();@b@  }@b@@b@  public void clear() {@b@    throw new UnsupportedOperationException();@b@  }@b@@b@  public boolean remove(Object object) {@b@    throw new UnsupportedOperationException();@b@  }@b@@b@  public boolean removeAll(Collection coll) {@b@    throw new UnsupportedOperationException();@b@  }@b@@b@  public boolean retainAll(Collection coll) {@b@    throw new UnsupportedOperationException();@b@  }@b@@b@  public ListIterator listIterator()@b@  {@b@    return UnmodifiableListIterator.decorate(getList().listIterator());@b@  }@b@@b@  public ListIterator listIterator(int index) {@b@    return UnmodifiableListIterator.decorate(getList().listIterator(index));@b@  }@b@@b@  public void add(int index, Object object) {@b@    throw new UnsupportedOperationException();@b@  }@b@@b@  public boolean addAll(int index, Collection coll) {@b@    throw new UnsupportedOperationException();@b@  }@b@@b@  public Object remove(int index) {@b@    throw new UnsupportedOperationException();@b@  }@b@@b@  public Object set(int index, Object object) {@b@    throw new UnsupportedOperationException();@b@  }@b@@b@  public List subList(int fromIndex, int toIndex) {@b@    List sub = getList().subList(fromIndex, toIndex);@b@    return new UnmodifiableList(sub);@b@  }@b@}