src/share/classes/java/util/LinkedHashMap.java

Print this page
rev 5028 : 7126277: alternative hashing


 219      *
 220      * @param  initialCapacity the initial capacity
 221      * @param  loadFactor      the load factor
 222      * @param  accessOrder     the ordering mode - <tt>true</tt> for
 223      *         access-order, <tt>false</tt> for insertion-order
 224      * @throws IllegalArgumentException if the initial capacity is negative
 225      *         or the load factor is nonpositive
 226      */
 227     public LinkedHashMap(int initialCapacity,
 228                          float loadFactor,
 229                          boolean accessOrder) {
 230         super(initialCapacity, loadFactor);
 231         this.accessOrder = accessOrder;
 232     }
 233 
 234     /**
 235      * Called by superclass constructors and pseudoconstructors (clone,
 236      * readObject) before any entries are inserted into the map.  Initializes
 237      * the chain.
 238      */

 239     void init() {
 240         header = new Entry<>(-1, null, null, null);
 241         header.before = header.after = header;
 242     }
 243 
 244     /**
 245      * Transfers all entries to new table array.  This method is called
 246      * by superclass resize.  It is overridden for performance, as it is
 247      * faster to iterate using our linked list.
 248      */
 249     void transfer(HashMap.Entry[] newTable) {

 250         int newCapacity = newTable.length;
 251         for (Entry<K,V> e = header.after; e != header; e = e.after) {


 252             int index = indexFor(e.hash, newCapacity);
 253             e.next = newTable[index];
 254             newTable[index] = e;
 255         }
 256     }
 257 
 258 
 259     /**
 260      * Returns <tt>true</tt> if this map maps one or more keys to the
 261      * specified value.
 262      *
 263      * @param value value whose presence in this map is to be tested
 264      * @return <tt>true</tt> if this map maps one or more keys to the
 265      *         specified value
 266      */
 267     public boolean containsValue(Object value) {
 268         // Overridden to take advantage of faster iterator
 269         if (value==null) {
 270             for (Entry e = header.after; e != header; e = e.after)
 271                 if (e.value==null)


 403 
 404     private class ValueIterator extends LinkedHashIterator<V> {
 405         public V next() { return nextEntry().value; }
 406     }
 407 
 408     private class EntryIterator extends LinkedHashIterator<Map.Entry<K,V>> {
 409         public Map.Entry<K,V> next() { return nextEntry(); }
 410     }
 411 
 412     // These Overrides alter the behavior of superclass view iterator() methods
 413     Iterator<K> newKeyIterator()   { return new KeyIterator();   }
 414     Iterator<V> newValueIterator() { return new ValueIterator(); }
 415     Iterator<Map.Entry<K,V>> newEntryIterator() { return new EntryIterator(); }
 416 
 417     /**
 418      * This override alters behavior of superclass put method. It causes newly
 419      * allocated entry to get inserted at the end of the linked list and
 420      * removes the eldest entry if appropriate.
 421      */
 422     void addEntry(int hash, K key, V value, int bucketIndex) {
 423         createEntry(hash, key, value, bucketIndex);
 424 
 425         // Remove eldest entry if instructed, else grow capacity if appropriate
 426         Entry<K,V> eldest = header.after;
 427         if (removeEldestEntry(eldest)) {
 428             removeEntryForKey(eldest.key);
 429         } else {
 430             if (size >= threshold)
 431                 resize(2 * table.length);
 432         }
 433     }
 434 
 435     /**
 436      * This override differs from addEntry in that it doesn't resize the
 437      * table or remove the eldest entry.
 438      */
 439     void createEntry(int hash, K key, V value, int bucketIndex) {
 440         HashMap.Entry<K,V> old = table[bucketIndex];
 441         Entry<K,V> e = new Entry<>(hash, key, value, old);
 442         table[bucketIndex] = e;
 443         e.addBefore(header);
 444         size++;
 445     }
 446 
 447     /**
 448      * Returns <tt>true</tt> if this map should remove its eldest entry.
 449      * This method is invoked by <tt>put</tt> and <tt>putAll</tt> after
 450      * inserting a new entry into the map.  It provides the implementor
 451      * with the opportunity to remove the eldest entry each time a new one




 219      *
 220      * @param  initialCapacity the initial capacity
 221      * @param  loadFactor      the load factor
 222      * @param  accessOrder     the ordering mode - <tt>true</tt> for
 223      *         access-order, <tt>false</tt> for insertion-order
 224      * @throws IllegalArgumentException if the initial capacity is negative
 225      *         or the load factor is nonpositive
 226      */
 227     public LinkedHashMap(int initialCapacity,
 228                          float loadFactor,
 229                          boolean accessOrder) {
 230         super(initialCapacity, loadFactor);
 231         this.accessOrder = accessOrder;
 232     }
 233 
 234     /**
 235      * Called by superclass constructors and pseudoconstructors (clone,
 236      * readObject) before any entries are inserted into the map.  Initializes
 237      * the chain.
 238      */
 239     @Override
 240     void init() {
 241         header = new Entry<>(-1, null, null, null);
 242         header.before = header.after = header;
 243     }
 244 
 245     /**
 246      * Transfers all entries to new table array.  This method is called
 247      * by superclass resize.  It is overridden for performance, as it is
 248      * faster to iterate using our linked list.
 249      */
 250     @Override
 251     void transfer(HashMap.Entry[] newTable, boolean rehash) {
 252         int newCapacity = newTable.length;
 253         for (Entry<K,V> e = header.after; e != header; e = e.after) {
 254             if (rehash) 
 255                 e.hash = (e.key == null) ? 0 : hash(e.key);
 256             int index = indexFor(e.hash, newCapacity);
 257             e.next = newTable[index];
 258             newTable[index] = e;
 259         }
 260     }
 261 
 262 
 263     /**
 264      * Returns <tt>true</tt> if this map maps one or more keys to the
 265      * specified value.
 266      *
 267      * @param value value whose presence in this map is to be tested
 268      * @return <tt>true</tt> if this map maps one or more keys to the
 269      *         specified value
 270      */
 271     public boolean containsValue(Object value) {
 272         // Overridden to take advantage of faster iterator
 273         if (value==null) {
 274             for (Entry e = header.after; e != header; e = e.after)
 275                 if (e.value==null)


 407 
 408     private class ValueIterator extends LinkedHashIterator<V> {
 409         public V next() { return nextEntry().value; }
 410     }
 411 
 412     private class EntryIterator extends LinkedHashIterator<Map.Entry<K,V>> {
 413         public Map.Entry<K,V> next() { return nextEntry(); }
 414     }
 415 
 416     // These Overrides alter the behavior of superclass view iterator() methods
 417     Iterator<K> newKeyIterator()   { return new KeyIterator();   }
 418     Iterator<V> newValueIterator() { return new ValueIterator(); }
 419     Iterator<Map.Entry<K,V>> newEntryIterator() { return new EntryIterator(); }
 420 
 421     /**
 422      * This override alters behavior of superclass put method. It causes newly
 423      * allocated entry to get inserted at the end of the linked list and
 424      * removes the eldest entry if appropriate.
 425      */
 426     void addEntry(int hash, K key, V value, int bucketIndex) {
 427         super.addEntry(hash, key, value, bucketIndex);
 428         
 429         // Remove eldest entry if instructed
 430         Entry<K,V> eldest = header.after;
 431         if (removeEldestEntry(eldest)) {
 432             removeEntryForKey(eldest.key);



 433         }
 434     }
 435 
 436     /**
 437      * This override differs from addEntry in that it doesn't resize the
 438      * table or remove the eldest entry.
 439      */
 440     void createEntry(int hash, K key, V value, int bucketIndex) {
 441         HashMap.Entry<K,V> old = table[bucketIndex];
 442         Entry<K,V> e = new Entry<>(hash, key, value, old);
 443         table[bucketIndex] = e;
 444         e.addBefore(header);
 445         size++;
 446     }
 447 
 448     /**
 449      * Returns <tt>true</tt> if this map should remove its eldest entry.
 450      * This method is invoked by <tt>put</tt> and <tt>putAll</tt> after
 451      * inserting a new entry into the map.  It provides the implementor
 452      * with the opportunity to remove the eldest entry each time a new one