⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sequencedhashmap.java

📁 Java有关XML编程需要用到axis 的源代码 把里面bin下的包导入相应的Java工程 进行使用
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* * Copyright 2002-2004 The Apache Software Foundation. *  * 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. */package org.apache.axis.collections;import org.apache.axis.i18n.Messages;import java.io.Externalizable;import java.io.IOException;import java.io.ObjectInput;import java.io.ObjectOutput;import java.util.AbstractCollection;import java.util.AbstractSet;import java.util.ArrayList;import java.util.Collection;import java.util.Collections;import java.util.ConcurrentModificationException;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.NoSuchElementException;import java.util.Set;/** *  A map of objects whose mapping entries are sequenced based on the order in *  which they were added.  This data structure has fast <i>O(1)</i> search *  time, deletion time, and insertion time. * *  <p>Although this map is sequenced, it cannot implement {@link *  java.util.List} because of incompatible interface definitions.  The remove *  methods in List and Map have different return values (see: {@link *  java.util.List#remove(Object)} and {@link java.util.Map#remove(Object)}). * *  <p>This class is not thread safe.  When a thread safe implementation is *  required, use {@link Collections#synchronizedMap(Map)} as it is documented, *  or use explicit synchronization controls. * * @since Commons Collections 2.0 *  * @author <a href="mailto:mas@apache.org">Michael A. Smith</A> * @author <a href="mailto:dlr@collab.net">Daniel Rall</a> * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> * @author Stephen Colebourne */public class SequencedHashMap implements Map, Cloneable, Externalizable {    /**     *  {@link java.util.Map.Entry} that doubles as a node in the linked list     *  of sequenced mappings.       **/    private static class Entry implements Map.Entry {        // Note: This class cannot easily be made clonable.  While the actual        // implementation of a clone would be simple, defining the semantics is        // difficult.  If a shallow clone is implemented, then entry.next.prev !=        // entry, which is unintuitive and probably breaks all sorts of assumptions        // in code that uses this implementation.  If a deep clone is        // implementated, then what happens when the linked list is cyclical (as is        // the case with SequencedHashMap)?  It's impossible to know in the clone        // when to stop cloning, and thus you end up in a recursive loop,        // continuously cloning the "next" in the list.        private final Object key;        private Object value;        // package private to allow the SequencedHashMap to access and manipulate        // them.        Entry next = null;        Entry prev = null;        public Entry(Object key, Object value) {            this.key = key;            this.value = value;        }        // per Map.Entry.getKey()        public Object getKey() {            return this.key;        }        // per Map.Entry.getValue()        public Object getValue() {            return this.value;        }        // per Map.Entry.setValue()        public Object setValue(Object value) {            Object oldValue = this.value;            this.value = value;            return oldValue;        }        public int hashCode() {            // implemented per api docs for Map.Entry.hashCode()            return ((getKey() == null ? 0 : getKey().hashCode()) ^ (getValue() == null ? 0 : getValue().hashCode()));        }        public boolean equals(Object obj) {            if (obj == null)                return false;            if (obj == this)                return true;            if (!(obj instanceof Map.Entry))                return false;            Map.Entry other = (Map.Entry) obj;            // implemented per api docs for Map.Entry.equals(Object)             return (                (getKey() == null ? other.getKey() == null : getKey().equals(other.getKey()))                    && (getValue() == null ? other.getValue() == null : getValue().equals(other.getValue())));        }        public String toString() {            return "[" + getKey() + "=" + getValue() + "]";        }    }    /**     *  Construct an empty sentinel used to hold the head (sentinel.next) and the     *  tail (sentinel.prev) of the list.  The sentinal has a <code>null</code>     *  key and value.     **/    private static final Entry createSentinel() {        Entry s = new Entry(null, null);        s.prev = s;        s.next = s;        return s;    }    /**     *  Sentinel used to hold the head and tail of the list of entries.     **/    private Entry sentinel;    /**     *  Map of keys to entries     **/    private HashMap entries;    /**     *  Holds the number of modifications that have occurred to the map,     *  excluding modifications made through a collection view's iterator     *  (e.g. entrySet().iterator().remove()).  This is used to create a     *  fail-fast behavior with the iterators.     **/    private transient long modCount = 0;    /**     *  Construct a new sequenced hash map with default initial size and load     *  factor.     **/    public SequencedHashMap() {        sentinel = createSentinel();        entries = new HashMap();    }    /**     *  Construct a new sequenced hash map with the specified initial size and     *  default load factor.     *     *  @param initialSize the initial size for the hash table      *     *  @see HashMap#HashMap(int)     **/    public SequencedHashMap(int initialSize) {        sentinel = createSentinel();        entries = new HashMap(initialSize);    }    /**     *  Construct a new sequenced hash map with the specified initial size and     *  load factor.     *     *  @param initialSize the initial size for the hash table      *     *  @param loadFactor the load factor for the hash table.     *     *  @see HashMap#HashMap(int,float)     **/    public SequencedHashMap(int initialSize, float loadFactor) {        sentinel = createSentinel();        entries = new HashMap(initialSize, loadFactor);    }    /**     *  Construct a new sequenced hash map and add all the elements in the     *  specified map.  The order in which the mappings in the specified map are     *  added is defined by {@link #putAll(Map)}.       **/    public SequencedHashMap(Map m) {        this();        putAll(m);    }    /**     *  Removes an internal entry from the linked list.  This does not remove     *  it from the underlying map.     **/    private void removeEntry(Entry entry) {        entry.next.prev = entry.prev;        entry.prev.next = entry.next;    }    /**     *  Inserts a new internal entry to the tail of the linked list.  This does     *  not add the entry to the underlying map.     **/    private void insertEntry(Entry entry) {        entry.next = sentinel;        entry.prev = sentinel.prev;        sentinel.prev.next = entry;        sentinel.prev = entry;    }    // per Map.size()    /**     *  Implements {@link Map#size()}.     */    public int size() {        // use the underlying Map's size since size is not maintained here.        return entries.size();    }    /**     *  Implements {@link Map#isEmpty()}.     */    public boolean isEmpty() {        // for quick check whether the map is entry, we can check the linked list        // and see if there's anything in it.        return sentinel.next == sentinel;    }    /**     *  Implements {@link Map#containsKey(Object)}.     */    public boolean containsKey(Object key) {        // pass on to underlying map implementation        return entries.containsKey(key);    }    /**     *  Implements {@link Map#containsValue(Object)}.     */    public boolean containsValue(Object value) {        // unfortunately, we cannot just pass this call to the underlying map        // because we are mapping keys to entries, not keys to values.  The        // underlying map doesn't have an efficient implementation anyway, so this        // isn't a big deal.        // do null comparison outside loop so we only need to do it once.  This        // provides a tighter, more efficient loop at the expense of slight        // code duplication.        if (value == null) {            for (Entry pos = sentinel.next; pos != sentinel; pos = pos.next) {                if (pos.getValue() == null)                    return true;            }        } else {            for (Entry pos = sentinel.next; pos != sentinel; pos = pos.next) {                if (value.equals(pos.getValue()))                    return true;            }        }        return false;    }    /**     *  Implements {@link Map#get(Object)}.     */    public Object get(Object o) {        // find entry for the specified key object        Entry entry = (Entry) entries.get(o);        if (entry == null)            return null;        return entry.getValue();    }    /**     *  Return the entry for the "oldest" mapping.  That is, return the Map.Entry     *  for the key-value pair that was first put into the map when compared to     *  all the other pairings in the map.  This behavior is equivalent to using     *  <code>entrySet().iterator().next()</code>, but this method provides an     *  optimized implementation.     *     *  @return The first entry in the sequence, or <code>null</code> if the     *  map is empty.     **/    public Map.Entry getFirst() {        // sentinel.next points to the "first" element of the sequence -- the head        // of the list, which is exactly the entry we need to return.  We must test        // for an empty list though because we don't want to return the sentinel!        return (isEmpty()) ? null : sentinel.next;    }    /**     *  Return the key for the "oldest" mapping.  That is, return the key for the     *  mapping that was first put into the map when compared to all the other     *  objects in the map.  This behavior is equivalent to using     *  <code>getFirst().getKey()</code>, but this method provides a slightly     *  optimized implementation.     *     *  @return The first key in the sequence, or <code>null</code> if the     *  map is empty.     **/    public Object getFirstKey() {        // sentinel.next points to the "first" element of the sequence -- the head        // of the list -- and the requisite key is returned from it.  An empty list        // does not need to be tested.  In cases where the list is empty,        // sentinel.next will point to the sentinel itself which has a null key,        // which is exactly what we would want to return if the list is empty (a        // nice convient way to avoid test for an empty list)        return sentinel.next.getKey();    }    /**     *  Return the value for the "oldest" mapping.  That is, return the value for     *  the mapping that was first put into the map when compared to all the     *  other objects in the map.  This behavior is equivalent to using     *  <code>getFirst().getValue()</code>, but this method provides a slightly     *  optimized implementation.     *     *  @return The first value in the sequence, or <code>null</code> if the     *  map is empty.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -