/** * Creates an entry to store the key-value data. * <p> * This implementation creates a new HashEntry instance. * Subclasses can override this to return a different storage class, * or implement caching. * * @param next the next entry in sequence * @param hashCode the hash code to use * @param key the key to store * @param value the value to store * @return the newly created entry */ protected HashEntry<K, V> createEntry(final HashEntry<K, V> next, final int hashCode, final K key, final V value) { return new HashEntry<>(next, hashCode, convertKey(key), value); }
/** * Checks whether the map contains the specified key. * * @param key the key to search for * @return true if the map contains the key */ @Override public boolean containsKey(Object key) { key = convertKey(key); final int hashCode = hash(key); HashEntry<K, V> entry = data[hashIndex(hashCode, data.length)]; // no local for hash index while (entry != null) { if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) { return true; } entry = entry.next; } return false; }
/** * Gets the entry mapped to the key specified. * <p> * This method exists for subclasses that may need to perform a multi-step * process accessing the entry. The public methods in this class don't use this * method to gain a small performance boost. * * @param key the key * @return the entry, null if no match */ protected HashEntry<K, V> getEntry(Object key) { key = convertKey(key); final int hashCode = hash(key); HashEntry<K, V> entry = data[hashIndex(hashCode, data.length)]; // no local for hash index while (entry != null) { if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) { return entry; } entry = entry.next; } return null; }
/** * Gets the value mapped to the key specified. * * @param key the key * @return the mapped value, null if no match */ @Override public V get(Object key) { key = convertKey(key); final int hashCode = hash(key); HashEntry<K, V> entry = data[hashIndex(hashCode, data.length)]; // no local for hash index while (entry != null) { if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) { return entry.getValue(); } entry = entry.next; } return null; }
/** * Removes the specified mapping from this map. * * @param key the mapping to remove * @return the value mapped to the removed key, null if key not in map */ @Override public V remove(Object key) { key = convertKey(key); final int hashCode = hash(key); final int index = hashIndex(hashCode, data.length); HashEntry<K, V> entry = data[index]; HashEntry<K, V> previous = null; while (entry != null) { if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) { final V oldValue = entry.getValue(); removeMapping(entry, index, previous); return oldValue; } previous = entry; entry = entry.next; } return null; }
/** * Puts a key-value mapping into this map. * * @param key the key to add * @param value the value to add * @return the value previously mapped to this key, null if none */ @Override public V put(final K key, final V value) { final Object convertedKey = convertKey(key); final int hashCode = hash(convertedKey); final int index = hashIndex(hashCode, data.length); HashEntry<K, V> entry = data[index]; while (entry != null) { if (entry.hashCode == hashCode && isEqualKey(convertedKey, entry.key)) { final V oldValue = entry.getValue(); updateEntry(entry, value); return oldValue; } entry = entry.next; } addMapping(index, hashCode, key, value); return null; }