📄 inthashmap.java
字号:
return true; } } } return false; } /** * Special-case code for containsValue with null argument * * @return boolean true if there is a null value in this map */ private boolean containsNullValue() { Entry tab[] = table; for (int i = 0; i < tab.length; i++) { for (Entry e = tab[i]; e != null; e = e.next) { if (e.value == null) { return true; } } } return false; } /** * Returns a shallow copy of this <tt>HashMap</tt> instance: the keys and values themselves * are not cloned. * * @return a shallow copy of this map. */ public Object clone() throws CloneNotSupportedException { IntHashMap result = null; try { result = (IntHashMap)super.clone(); result.table = new Entry[table.length]; result.entrySet = null; result.modCount = 0; result.size = 0; result.init(); result.putAllForCreate(this); } catch (CloneNotSupportedException e) { // assert false; } return result; } /** * @author jcompagner */ public static class Entry { final int key; Object value; Entry next; /** * Create new entry. * * @param k * @param v * @param n */ Entry(int k, Object v, Entry n) { value = v; next = n; key = k; } /** * @return The int key of this entry */ public int getKey() { return key; } /** * @return Gets the value object of this entry */ public Object getValue() { return value; } /** * @param newValue * @return The previous value */ public Object setValue(Object newValue) { Object oldValue = value; value = newValue; return oldValue; } /** * @see java.lang.Object#equals(java.lang.Object) */ public boolean equals(Object o) { if (!(o instanceof Entry)) { return false; } Entry e = (Entry)o; int k1 = getKey(); int k2 = e.getKey(); if (k1 == k2) { Object v1 = getValue(); Object v2 = e.getValue(); if (v1 == v2 || (v1 != null && v1.equals(v2))) { return true; } } return false; } /** * @see java.lang.Object#hashCode() */ public int hashCode() { return key ^ (value == null ? 0 : value.hashCode()); } /** * @see java.lang.Object#toString() */ public String toString() { return getKey() + "=" + getValue(); //$NON-NLS-1$ } } /** * Add a new entry with the specified key, value and hash code to the specified bucket. It is * the responsibility of this method to resize the table if appropriate. * * Subclass overrides this to alter the behavior of put method. * * @param key * @param value * @param bucketIndex */ void addEntry(int key, Object value, int bucketIndex) { table[bucketIndex] = new Entry(key, value, table[bucketIndex]); if (size++ >= threshold) { resize(2 * table.length); } } /** * Like addEntry except that this version is used when creating entries as part of Map * construction or "pseudo-construction" (cloning, deserialization). This version needn't worry * about resizing the table. * * Subclass overrides this to alter the behavior of HashMap(Map), clone, and readObject. * * @param key * @param value * @param bucketIndex */ void createEntry(int key, Object value, int bucketIndex) { table[bucketIndex] = new Entry(key, value, table[bucketIndex]); size++; } private abstract class HashIterator implements Iterator { Entry next; // next entry to return int expectedModCount; // For fast-fail int index; // current slot Entry current; // current entry HashIterator() { expectedModCount = modCount; Entry[] t = table; int i = t.length; Entry n = null; if (size != 0) { // advance to first entry while (i > 0 && (n = t[--i]) == null) { /* NoOp */; } } next = n; index = i; } /** * @see java.util.Iterator#hasNext() */ public boolean hasNext() { return next != null; } Entry nextEntry() { if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } Entry e = next; if (e == null) { throw new NoSuchElementException(); } Entry n = e.next; Entry[] t = table; int i = index; while (n == null && i > 0) { n = t[--i]; } index = i; next = n; return current = e; } /** * @see java.util.Iterator#remove() */ public void remove() { if (current == null) { throw new IllegalStateException(); } if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } int k = current.key; current = null; removeEntryForKey(k); expectedModCount = modCount; } } private class ValueIterator extends HashIterator { /** * @see java.util.Iterator#next() */ public Object next() { return nextEntry().value; } } private class KeyIterator extends HashIterator { /** * @see java.util.Iterator#next() */ public Object next() { return new Integer(nextEntry().getKey()); } } private class EntryIterator extends HashIterator { /** * @see java.util.Iterator#next() */ public Object next() { return nextEntry(); } } // Subclass overrides these to alter behavior of views' iterator() method Iterator newKeyIterator() { return new KeyIterator(); } Iterator newValueIterator() { return new ValueIterator(); } Iterator newEntryIterator() { return new EntryIterator(); } // Views private transient Set entrySet = null; /** * Returns a set view of the keys contained in this map. The set is backed by the map, so * changes to the map are reflected in the set, and vice-versa. The set supports element * removal, which removes the corresponding mapping from this map, via the * <tt>Iterator.remove</tt>, <tt>Set.remove</tt>, <tt>removeAll</tt>, * <tt>retainAll</tt>, and <tt>clear</tt> operations. It does not support the <tt>add</tt> * or <tt>addAll</tt> operations. * * @return a set view of the keys contained in this map. */ public Set keySet() { Set ks = keySet; return (ks != null ? ks : (keySet = new KeySet())); } private class KeySet extends AbstractSet { /** * @see java.util.AbstractCollection#iterator() */ public Iterator iterator() { return newKeyIterator(); } /** * @see java.util.AbstractCollection#size() */ public int size() { return size; } /** * @see java.util.AbstractCollection#contains(java.lang.Object) */ public boolean contains(Object o) { if (o instanceof Number) { return containsKey(((Number)o).intValue()); } return false; } /** * @see java.util.AbstractCollection#remove(java.lang.Object) */ public boolean remove(Object o) { if (o instanceof Number) { return removeEntryForKey(((Number)o).intValue()) != null; } return false; } /** * @see java.util.AbstractCollection#clear() */ public void clear() { IntHashMap.this.clear(); } } /** * Returns a collection view of the values contained in this map. The collection is backed by * the map, so changes to the map are reflected in the collection, and vice-versa. The * collection supports element removal, which removes the corresponding mapping from this map, * via the <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>, <tt>removeAll</tt>, * <tt>retainAll</tt>, and <tt>clear</tt> operations. It does not support the <tt>add</tt> * or <tt>addAll</tt> operations. * * @return a collection view of the values contained in this map. */ public Collection values() { Collection vs = values; return (vs != null ? vs : (values = new Values())); } private class Values extends AbstractCollection { /** * @see java.util.AbstractCollection#iterator() */ public Iterator iterator() { return newValueIterator(); } /** * @see java.util.AbstractCollection#size() */ public int size() { return size; } /** * @see java.util.AbstractCollection#contains(java.lang.Object) */ public boolean contains(Object o) { return containsValue(o); } /** * @see java.util.AbstractCollection#clear() */ public void clear() { IntHashMap.this.clear(); } } /** * Returns a collection view of the mappings contained in this map. Each element in the returned * collection is a <tt>Map.Entry</tt>. The collection is backed by the map, so changes to the * map are reflected in the collection, and vice-versa. The collection supports element removal, * which removes the corresponding mapping from the map, via the <tt>Iterator.remove</tt>, * <tt>Collection.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt>, and * <tt>clear</tt> operations. It does not support the <tt>add</tt> or <tt>addAll</tt> * operations. * * @return a collection view of the mappings contained in this map. * @see Map.Entry */ public Set entrySet() { Set es = entrySet; return (es != null ? es : (entrySet = new EntrySet())); } private class EntrySet extends AbstractSet { /** * @see java.util.AbstractCollection#iterator() */ public Iterator iterator() { return newEntryIterator(); } /** * @see java.util.AbstractCollection#contains(java.lang.Object) */ public boolean contains(Object o) { if (!(o instanceof Entry)) { return false; } Entry e = (Entry)o; Entry candidate = getEntry(e.getKey()); return candidate != null && candidate.equals(e); } /** * @see java.util.AbstractCollection#remove(java.lang.Object) */ public boolean remove(Object o) { return removeMapping(o) != null; } /** * @see java.util.AbstractCollection#size() */ public int size() { return size; } /** * @see java.util.AbstractCollection#clear() */ public void clear() { IntHashMap.this.clear(); } } /** * Save the state of the <tt>HashMap</tt> instance to a stream (i.e., serialize it). * * @param s * The ObjectOutputStream * @throws IOException * * @serialData The <i>capacity</i> of the HashMap (the length of the bucket array) is emitted * (int), followed by the <i>size</i> of the HashMap (the number of key-value * mappings), followed by the key (Object) and value (Object) for each key-value * mapping represented by the HashMap The key-value mappings are emitted in the * order that they are returned by <tt>entrySet().iterator()</tt>. * */ private void writeObject(java.io.ObjectOutputStream s) throws IOException { // Write out the threshold, loadfactor, and any hidden stuff s.defaultWriteObject(); // Write out number of buckets s.writeInt(table.length); // Write out size (number of Mappings) s.writeInt(size); // Write out keys and values (alternating) for (Iterator i = entrySet().iterator(); i.hasNext();) { Entry e = (Entry)i.next(); s.writeInt(e.getKey()); s.writeObject(e.getValue()); } } private static final long serialVersionUID = 362498820763181265L; /** * Reconstitute the <tt>HashMap</tt> instance from a stream (i.e., deserialize it). * * @param s * @throws IOException * @throws ClassNotFoundException */ private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException { // Read in the threshold, loadfactor, and any hidden stuff s.defaultReadObject(); // Read in number of buckets and allocate the bucket array; int numBuckets = s.readInt(); table = new Entry[numBuckets]; init(); // Give subclass a chance to do its thing. // Read in size (number of Mappings) int size = s.readInt(); // Read the keys and values, and put the mappings in the HashMap for (int i = 0; i < size; i++) { int key = s.readInt(); Object value = s.readObject(); putForCreate(key, value); } } // These methods are used when serializing HashSets int capacity() { return table.length; } float loadFactor() { return loadFactor; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -