FileDocCategorySizeDatePackage
Hashtable.javaAPI DocAndroid 1.5 API30716Wed May 06 22:41:04 BST 2009java.util

Hashtable

public class Hashtable extends Dictionary implements Serializable, Cloneable, Map
Hashtable associates keys with values. Both keys and values cannot be null. The size of the Hashtable is the number of key/value pairs it contains. The capacity is the number of key/value pairs the Hashtable can hold. The load factor is a float value which determines how full the Hashtable gets before expanding the capacity. If the load factor of the Hashtable is exceeded, the capacity is doubled.
see
Enumeration
see
java.io.Serializable
see
java.lang.Object#equals
see
java.lang.Object#hashCode
since
Android 1.0

Fields Summary
private static final long
serialVersionUID
transient int
elementCount
transient Entry[]
elementData
private float
loadFactor
private int
threshold
transient int
firstSlot
transient int
lastSlot
transient int
modCount
private static final Enumeration
EMPTY_ENUMERATION
Constructors Summary
public Hashtable()
Constructs a new {@code Hashtable} using the default capacity and load factor.

since
Android 1.0

        this(11);
    
public Hashtable(int capacity)
Constructs a new {@code Hashtable} using the specified capacity and the default load factor.

param
capacity the initial capacity.
since
Android 1.0

        if (capacity >= 0) {
            elementCount = 0;
            elementData = newElementArray(capacity == 0 ? 1 : capacity);
            firstSlot = elementData.length;
            loadFactor = 0.75f;
            computeMaxSize();
        } else {
            throw new IllegalArgumentException();
        }
    
public Hashtable(int capacity, float loadFactor)
Constructs a new {@code Hashtable} using the specified capacity and load factor.

param
capacity the initial capacity.
param
loadFactor the initial load factor.
since
Android 1.0

        if (capacity >= 0 && loadFactor > 0) {
            elementCount = 0;
            firstSlot = capacity;
            elementData = newElementArray(capacity == 0 ? 1 : capacity);
            this.loadFactor = loadFactor;
            computeMaxSize();
        } else {
            throw new IllegalArgumentException();
        }
    
public Hashtable(Map map)
Constructs a new instance of {@code Hashtable} containing the mappings from the specified map.

param
map the mappings to add.
since
Android 1.0

        this(map.size() < 6 ? 11 : (map.size() * 4 / 3) + 11);
        putAll(map);
    
Methods Summary
public synchronized voidclear()
Removes all key/value pairs from this {@code Hashtable}, leaving the size zero and the capacity unchanged.

see
#isEmpty
see
#size
since
Android 1.0

        elementCount = 0;
        Arrays.fill(elementData, null);
        modCount++;
    
public synchronized java.lang.Objectclone()
Returns a new {@code Hashtable} with the same key/value pairs, capacity and load factor.

return
a shallow copy of this {@code Hashtable}.
see
java.lang.Cloneable
since
Android 1.0

        try {
            Hashtable<K, V> hashtable = (Hashtable<K, V>) super.clone();
            hashtable.elementData = elementData.clone();
            Entry<K, V> entry;
            for (int i = elementData.length; --i >= 0;) {
                if ((entry = elementData[i]) != null) {
                    hashtable.elementData[i] = (Entry<K, V>) entry.clone();
                }
            }
            return hashtable;
        } catch (CloneNotSupportedException e) {
            return null;
        }
    
private voidcomputeMaxSize()

        threshold = (int) (elementData.length * loadFactor);
    
public synchronized booleancontains(java.lang.Object value)
Returns true if this {@code Hashtable} contains the specified object as the value of at least one of the key/value pairs.

param
value the object to look for as a value in this {@code Hashtable}.
return
{@code true} if object is a value in this {@code Hashtable}, {@code false} otherwise.
see
#containsKey
see
java.lang.Object#equals
since
Android 1.0

        if (value == null) {
            throw new NullPointerException();
        }

        for (int i = elementData.length; --i >= 0;) {
            Entry<K, V> entry = elementData[i];
            while (entry != null) {
                if (value.equals(entry.value)) {
                    return true;
                }
                entry = entry.next;
            }
        }
        return false;
    
public synchronized booleancontainsKey(java.lang.Object key)
Returns true if this {@code Hashtable} contains the specified object as a key of one of the key/value pairs.

param
key the object to look for as a key in this {@code Hashtable}.
return
{@code true} if object is a key in this {@code Hashtable}, {@code false} otherwise.
see
#contains
see
java.lang.Object#equals
since
Android 1.0

        return getEntry(key) != null;
    
public booleancontainsValue(java.lang.Object value)
Searches this {@code Hashtable} for the specified value.

param
value the object to search for.
return
{@code true} if {@code value} is a value of this {@code Hashtable}, {@code false} otherwise.
since
Android 1.0

        return contains(value);
    
public synchronized java.util.Enumerationelements()
Returns an enumeration on the values of this {@code Hashtable}. The results of the Enumeration may be affected if the contents of this {@code Hashtable} are modified.

return
an enumeration of the values of this {@code Hashtable}.
see
#keys
see
#size
see
Enumeration
since
Android 1.0

        if (elementCount == 0) {
            return (Enumeration<V>) EMPTY_ENUMERATION;
        }
        return new HashEnumerator<V>(false);
    
public java.util.SetentrySet()
Returns a set of the mappings contained in this {@code Hashtable}. Each element in the set is a {@link Map.Entry}. The set is backed by this {@code Hashtable} so changes to one are reflected by the other. The set does not support adding.

return
a set of the mappings.
since
Android 1.0

        return new Collections.SynchronizedSet<Map.Entry<K, V>>(
                new AbstractSet<Map.Entry<K, V>>() {
                    @Override
                    public int size() {
                        synchronized (Hashtable.this) {
                            return elementCount;
                        }
                    }

                    @Override
                    public void clear() {
                        Hashtable.this.clear();
                    }

                    @Override
                    @SuppressWarnings("unchecked")
                    public boolean remove(Object object) {
                        synchronized (Hashtable.this) {
                            if (contains(object)) {
                                Hashtable.this
                                        .remove(((Map.Entry<K, V>) object)
                                                .getKey());
                                return true;
                            }
                            return false;
                        }
                    }

                    @Override
                    @SuppressWarnings("unchecked")
                    public boolean contains(Object object) {
                        synchronized (Hashtable.this) {
                            Entry<K, V> entry = getEntry(((Map.Entry<K, V>) object)
                                    .getKey());
                            return object.equals(entry);
                        }
                    }

                    @Override
                    public Iterator<Map.Entry<K, V>> iterator() {
                        return new HashIterator<Map.Entry<K, V>>(
                                new MapEntry.Type<Map.Entry<K, V>, K, V>() {
                                    public Map.Entry<K, V> get(
                                            MapEntry<K, V> entry) {
                                        return entry;
                                    }
                                });
                    }
                }, this);
    
public synchronized booleanequals(java.lang.Object object)
Compares this {@code Hashtable} with the specified object and indicates if they are equal. In order to be equal, {@code object} must be an instance of Map and contain the same key/value pairs.

param
object the object to compare with this object.
return
{@code true} if the specified object is equal to this Map, {@code false} otherwise.
see
#hashCode
since
Android 1.0

        if (this == object) {
            return true;
        }
        if (object instanceof Map) {
            Map<?, ?> map = (Map<?, ?>) object;
            if (size() != map.size()) {
                return false;
            }

            Set<Map.Entry<K, V>> entries = entrySet();
            for (Map.Entry<?, ?> e : map.entrySet()) {
                if (!entries.contains(e)) {
                    return false;
                }
            }
            return true;
        }
        return false;
    
public synchronized Vget(java.lang.Object key)
Returns the value associated with the specified key in this {@code Hashtable}.

param
key the key of the value returned.
return
the value associated with the specified key, or {@code null} if the specified key does not exist.
see
#put
since
Android 1.0

        int hash = key.hashCode();
        int index = (hash & 0x7FFFFFFF) % elementData.length;
        Entry<K, V> entry = elementData[index];
        while (entry != null) {
            if (entry.equalsKey(key, hash)) {
                return entry.value;
            }
            entry = entry.next;
        }
        return null;
    
java.util.Hashtable$EntrygetEntry(java.lang.Object key)

        int hash = key.hashCode();
        int index = (hash & 0x7FFFFFFF) % elementData.length;
        Entry<K, V> entry = elementData[index];
        while (entry != null) {
            if (entry.equalsKey(key, hash)) {
                return entry;
            }
            entry = entry.next;
        }
        return null;
    
public synchronized inthashCode()

        int result = 0;
        Iterator<Map.Entry<K, V>> it = entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<K, V> entry = it.next();
            Object key = entry.getKey();
            Object value = entry.getValue();
            int hash = (key != this ? key.hashCode() : 0)
                    ^ (value != this ? (value != null ? value.hashCode() : 0)
                            : 0);
            result += hash;
        }
        return result;
    
public synchronized booleanisEmpty()
Returns true if this {@code Hashtable} has no key/value pairs.

return
{@code true} if this {@code Hashtable} has no key/value pairs, {@code false} otherwise.
see
#size
since
Android 1.0

        return elementCount == 0;
    
public java.util.SetkeySet()
Returns a set of the keys contained in this {@code Hashtable}. The set is backed by this {@code Hashtable} so changes to one are reflected by the other. The set does not support adding.

return
a set of the keys.
since
Android 1.0

        return new Collections.SynchronizedSet<K>(new AbstractSet<K>() {
            @Override
            public boolean contains(Object object) {
                synchronized (Hashtable.this) {
                    return containsKey(object);
                }
            }

            @Override
            public int size() {
                synchronized (Hashtable.this) {
                    return elementCount;
                }
            }

            @Override
            public void clear() {
                Hashtable.this.clear();
            }

            @Override
            public boolean remove(Object key) {
                synchronized (Hashtable.this) {
                    if (containsKey(key)) {
                        Hashtable.this.remove(key);
                        return true;
                    }
                    return false;
                }
            }

            @Override
            public Iterator<K> iterator() {
                return new HashIterator<K>(new MapEntry.Type<K, K, V>() {
                    public K get(MapEntry<K, V> entry) {
                        return entry.key;
                    }
                });
            }
        }, this);
    
public synchronized java.util.Enumerationkeys()
Returns an enumeration on the keys of this {@code Hashtable} instance. The results of the enumeration may be affected if the contents of this {@code Hashtable} are modified.

return
an enumeration of the keys of this {@code Hashtable}.
see
#elements
see
#size
see
Enumeration
since
Android 1.0

        if (elementCount == 0) {
            return (Enumeration<K>) EMPTY_ENUMERATION;
        }
        return new HashEnumerator<K>(true);
    
private java.util.Hashtable$Entry[]newElementArray(int size)

        return new Entry[size];
    
private static java.util.Hashtable$EntrynewEntry(K key, V value, int hash)


                
        return new Entry<K, V>(key, value);
    
public synchronized Vput(K key, V value)
Associate the specified value with the specified key in this {@code Hashtable}. If the key already exists, the old value is replaced. The key and value cannot be null.

param
key the key to add.
param
value the value to add.
return
the old value associated with the specified key, or {@code null} if the key did not exist.
see
#elements
see
#get
see
#keys
see
java.lang.Object#equals
since
Android 1.0

        if (key != null && value != null) {
            int hash = key.hashCode();
            int index = (hash & 0x7FFFFFFF) % elementData.length;
            Entry<K, V> entry = elementData[index];
            while (entry != null && !entry.equalsKey(key, hash)) {
                entry = entry.next;
            }
            if (entry == null) {
                modCount++;
                if (++elementCount > threshold) {
                    rehash();
                    index = (hash & 0x7FFFFFFF) % elementData.length;
                }
                if (index < firstSlot) {
                    firstSlot = index;
                }
                if (index > lastSlot) {
                    lastSlot = index;
                }
                entry = newEntry(key, value, hash);
                entry.next = elementData[index];
                elementData[index] = entry;
                return null;
            }
            V result = entry.value;
            entry.value = value;
            return result;
        }
        throw new NullPointerException();
    
public synchronized voidputAll(java.util.Map map)
Copies every mapping to this {@code Hashtable} from the specified map.

param
map the map to copy mappings from.
since
Android 1.0

        for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) {
            put(entry.getKey(), entry.getValue());
        }
    
private voidreadObject(java.io.ObjectInputStream stream)

        stream.defaultReadObject();
        int length = stream.readInt();
        elementData = newElementArray(length);
        elementCount = stream.readInt();
        for (int i = elementCount; --i >= 0;) {
            Object key = stream.readObject();
            int hash = key.hashCode();
            int index = (hash & 0x7FFFFFFF) % length;
            if (index < firstSlot) {
                firstSlot = index;
            }
            if (index > lastSlot) {
                lastSlot = index;
            }
            Entry<K, V> entry = newEntry((K) key, (V) stream.readObject(), hash);
            entry.next = elementData[index];
            elementData[index] = entry;
        }
    
protected voidrehash()
Increases the capacity of this {@code Hashtable}. This method is called when the size of this {@code Hashtable} exceeds the load factor.

since
Android 1.0

        int length = (elementData.length << 1) + 1;
        if (length == 0) {
            length = 1;
        }
        int newFirst = length;
        int newLast = -1;
        Entry<K, V>[] newData = newElementArray(length);
        for (int i = lastSlot + 1; --i >= firstSlot;) {
            Entry<K, V> entry = elementData[i];
            while (entry != null) {
                int index = (entry.getKeyHash() & 0x7FFFFFFF) % length;
                if (index < newFirst) {
                    newFirst = index;
                }
                if (index > newLast) {
                    newLast = index;
                }
                Entry<K, V> next = entry.next;
                entry.next = newData[index];
                newData[index] = entry;
                entry = next;
            }
        }
        firstSlot = newFirst;
        lastSlot = newLast;
        elementData = newData;
        computeMaxSize();
    
public synchronized Vremove(java.lang.Object key)
Removes the key/value pair with the specified key from this {@code Hashtable}.

param
key the key to remove.
return
the value associated with the specified key, or {@code null} if the specified key did not exist.
see
#get
see
#put
since
Android 1.0

        int hash = key.hashCode();
        int index = (hash & 0x7FFFFFFF) % elementData.length;
        Entry<K, V> last = null;
        Entry<K, V> entry = elementData[index];
        while (entry != null && !entry.equalsKey(key, hash)) {
            last = entry;
            entry = entry.next;
        }
        if (entry != null) {
            modCount++;
            if (last == null) {
                elementData[index] = entry.next;
            } else {
                last.next = entry.next;
            }
            elementCount--;
            V result = entry.value;
            entry.value = null;
            return result;
        }
        return null;
    
public synchronized intsize()
Returns the number of key/value pairs in this {@code Hashtable}.

return
the number of key/value pairs in this {@code Hashtable}.
see
#elements
see
#keys
since
Android 1.0

        return elementCount;
    
public synchronized java.lang.StringtoString()
Returns the string representation of this {@code Hashtable}.

return
the string representation of this {@code Hashtable}.
since
Android 1.0

        if (isEmpty()) {
            return "{}"; //$NON-NLS-1$
        }

        StringBuilder buffer = new StringBuilder(size() * 28);
        buffer.append('{");
        for (int i = lastSlot; i >= firstSlot; i--) {
            Entry<K, V> entry = elementData[i];
            while (entry != null) {
                if (entry.key != this) {
                    buffer.append(entry.key);
                } else {
                    // luni.04=this Map
                    buffer.append("(" + Messages.getString("luni.04") + ")"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
                }
                buffer.append('=");
                if (entry.value != this) {
                    buffer.append(entry.value);
                } else {
                    // luni.04=this Map
                    buffer.append("(" + Messages.getString("luni.04") + ")"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
                }
                buffer.append(", "); //$NON-NLS-1$
                entry = entry.next;
            }
        }
        // Remove the last ", "
        if (elementCount > 0) {
            buffer.setLength(buffer.length() - 2);
        }
        buffer.append('}");
        return buffer.toString();
    
public java.util.Collectionvalues()
Returns a collection of the values contained in this {@code Hashtable}. The collection is backed by this {@code Hashtable} so changes to one are reflected by the other. The collection does not support adding.

return
a collection of the values.
since
Android 1.0

        return new Collections.SynchronizedCollection<V>(
                new AbstractCollection<V>() {
                    @Override
                    public boolean contains(Object object) {
                        synchronized (Hashtable.this) {
                            return Hashtable.this.contains(object);
                        }
                    }

                    @Override
                    public int size() {
                        synchronized (Hashtable.this) {
                            return elementCount;
                        }
                    }

                    @Override
                    public void clear() {
                        Hashtable.this.clear();
                    }

                    @Override
                    public Iterator<V> iterator() {
                        return new HashIterator<V>(
                                new MapEntry.Type<V, K, V>() {
                                    public V get(MapEntry<K, V> entry) {
                                        return entry.value;
                                    }
                                });
                    }
                }, this);
    
private synchronized voidwriteObject(java.io.ObjectOutputStream stream)

        stream.defaultWriteObject();
        stream.writeInt(elementData.length);
        stream.writeInt(elementCount);
        for (int i = elementData.length; --i >= 0;) {
            Entry<K, V> entry = elementData[i];
            while (entry != null) {
                stream.writeObject(entry.key);
                stream.writeObject(entry.value);
                entry = entry.next;
            }
        }