src/share/classes/java/util/HashMap.java
Print this page
rev 4788 : Fix bunch of generics warnings
@@ -144,11 +144,11 @@
static final float DEFAULT_LOAD_FACTOR = 0.75f;
/**
* The table, resized as necessary. Length MUST Always be a power of two.
*/
- transient Entry[] table;
+ transient Entry<?,?>[] table;
/**
* The number of key-value mappings contained in this map.
*/
transient int size;
@@ -309,20 +309,21 @@
* The {@link #containsKey containsKey} operation may be used to
* distinguish these two cases.
*
* @see #put(Object, Object)
*/
+ @SuppressWarnings("unchecked")
public V get(Object key) {
if (key == null)
- return getForNullKey();
+ return (V)getForNullKey();
int hash = hash(key.hashCode());
- for (Entry<K,V> e = table[indexFor(hash, table.length)];
+ for (Entry<?,?> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
- return e.value;
+ return (V)e.value;
}
return null;
}
/**
@@ -330,12 +331,12 @@
* to index 0. This null case is split out into separate methods
* for the sake of performance in the two most commonly used
* operations (get and put), but incorporated with conditionals in
* others.
*/
- private V getForNullKey() {
- for (Entry<K,V> e = table[0]; e != null; e = e.next) {
+ private Object getForNullKey() {
+ for (Entry<?,?> e = table[0]; e != null; e = e.next) {
if (e.key == null)
return e.value;
}
return null;
}
@@ -355,19 +356,20 @@
/**
* Returns the entry associated with the specified key in the
* HashMap. Returns null if the HashMap contains no mapping
* for the key.
*/
+ @SuppressWarnings("unchecked")
final Entry<K,V> getEntry(Object key) {
int hash = (key == null) ? 0 : hash(key.hashCode());
- for (Entry<K,V> e = table[indexFor(hash, table.length)];
+ for (Entry<?,?> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
- return e;
+ return (Entry<K,V>)e;
}
return null;
}
@@ -386,11 +388,12 @@
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
- for (Entry<K,V> e = table[i]; e != null; e = e.next) {
+ for (@SuppressWarnings("unchecked")
+ Entry<K,V> e = (Entry<K,V>)table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
@@ -405,11 +408,12 @@
/**
* Offloaded version of put for null keys
*/
private V putForNullKey(V value) {
- for (Entry<K,V> e = table[0]; e != null; e = e.next) {
+ for (@SuppressWarnings("unchecked")
+ Entry<K,V> e = (Entry<K,V>)table[0]; e != null; e = e.next) {
if (e.key == null) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
@@ -433,11 +437,12 @@
/**
* Look for preexisting entry for key. This will never happen for
* clone or deserialize. It will only happen for construction if the
* input Map is a sorted map whose ordering is inconsistent w/ equals.
*/
- for (Entry<K,V> e = table[i]; e != null; e = e.next) {
+ for (@SuppressWarnings("unchecked")
+ Entry<?,V> e = (Entry<?,V>)table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k)))) {
e.value = value;
return;
@@ -465,37 +470,38 @@
* must be greater than current capacity unless current
* capacity is MAXIMUM_CAPACITY (in which case value
* is irrelevant).
*/
void resize(int newCapacity) {
- Entry[] oldTable = table;
+ Entry<?,?>[] oldTable = table;
int oldCapacity = oldTable.length;
if (oldCapacity == MAXIMUM_CAPACITY) {
threshold = Integer.MAX_VALUE;
return;
}
- Entry[] newTable = new Entry[newCapacity];
+ Entry<?,?>[] newTable = new Entry<?,?>[newCapacity];
transfer(newTable);
table = newTable;
threshold = (int)(newCapacity * loadFactor);
}
/**
* Transfers all entries from current table to newTable.
*/
- void transfer(Entry[] newTable) {
- Entry[] src = table;
+ @SuppressWarnings("unchecked")
+ void transfer(Entry<?,?>[] newTable) {
+ Entry<?,?>[] src = table;
int newCapacity = newTable.length;
for (int j = 0; j < src.length; j++) {
- Entry<K,V> e = src[j];
+ Entry<K,V> e = (Entry<K,V>)src[j];
if (e != null) {
src[j] = null;
do {
Entry<K,V> next = e.next;
int i = indexFor(e.hash, newCapacity);
- e.next = newTable[i];
+ e.next = (Entry<K,V>)newTable[i];
newTable[i] = e;
e = next;
} while (e != null);
}
}
@@ -558,11 +564,12 @@
* for this key.
*/
final Entry<K,V> removeEntryForKey(Object key) {
int hash = (key == null) ? 0 : hash(key.hashCode());
int i = indexFor(hash, table.length);
- Entry<K,V> prev = table[i];
+ @SuppressWarnings("unchecked")
+ Entry<K,V> prev = (Entry<K,V>)table[i];
Entry<K,V> e = prev;
while (e != null) {
Entry<K,V> next = e.next;
Object k;
@@ -589,15 +596,16 @@
*/
final Entry<K,V> removeMapping(Object o) {
if (!(o instanceof Map.Entry))
return null;
- Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
+ Map.Entry<?,?> entry = (Map.Entry<?,?>) o;
Object key = entry.getKey();
int hash = (key == null) ? 0 : hash(key.hashCode());
int i = indexFor(hash, table.length);
- Entry<K,V> prev = table[i];
+ @SuppressWarnings("unchecked")
+ Entry<K,V> prev = (Entry<K,V>)table[i];
Entry<K,V> e = prev;
while (e != null) {
Entry<K,V> next = e.next;
if (e.hash == hash && e.equals(entry)) {
@@ -621,11 +629,11 @@
* Removes all of the mappings from this map.
* The map will be empty after this call returns.
*/
public void clear() {
modCount++;
- Entry[] tab = table;
+ Entry<?,?>[] tab = table;
for (int i = 0; i < tab.length; i++)
tab[i] = null;
size = 0;
}
@@ -639,25 +647,25 @@
*/
public boolean containsValue(Object value) {
if (value == null)
return containsNullValue();
- Entry[] tab = table;
+ Entry<?,?>[] tab = table;
for (int i = 0; i < tab.length ; i++)
- for (Entry e = tab[i] ; e != null ; e = e.next)
+ for (Entry<?,?> e = tab[i] ; e != null ; e = e.next)
if (value.equals(e.value))
return true;
return false;
}
/**
* Special-case code for containsValue with null argument
*/
private boolean containsNullValue() {
- Entry[] tab = table;
+ Entry<?,?>[] tab = table;
for (int i = 0; i < tab.length ; i++)
- for (Entry e = tab[i] ; e != null ; e = e.next)
+ for (Entry<?,?> e = tab[i] ; e != null ; e = e.next)
if (e.value == null)
return true;
return false;
}
@@ -665,18 +673,19 @@
* 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
*/
+ @SuppressWarnings("unchecked")
public Object clone() {
HashMap<K,V> result = null;
try {
result = (HashMap<K,V>)super.clone();
} catch (CloneNotSupportedException e) {
// assert false;
}
- result.table = new Entry[table.length];
+ result.table = new Entry<?,?>[table.length];
result.entrySet = null;
result.modCount = 0;
result.size = 0;
result.init();
result.putAllForCreate(this);
@@ -715,11 +724,11 @@
}
public final boolean equals(Object o) {
if (!(o instanceof Map.Entry))
return false;
- Map.Entry e = (Map.Entry)o;
+ Map.Entry<?,?> e = (Map.Entry<?,?>)o;
Object k1 = getKey();
Object k2 = e.getKey();
if (k1 == k2 || (k1 != null && k1.equals(k2))) {
Object v1 = getValue();
Object v2 = e.getValue();
@@ -760,11 +769,12 @@
* method to resize the table if appropriate.
*
* Subclass overrides this to alter the behavior of put method.
*/
void addEntry(int hash, K key, V value, int bucketIndex) {
- Entry<K,V> e = table[bucketIndex];
+ @SuppressWarnings("unchecked")
+ Entry<K,V> e = (Entry<K,V>)table[bucketIndex];
table[bucketIndex] = new Entry<>(hash, key, value, e);
if (size++ >= threshold)
resize(2 * table.length);
}
@@ -775,48 +785,50 @@
*
* Subclass overrides this to alter the behavior of HashMap(Map),
* clone, and readObject.
*/
void createEntry(int hash, K key, V value, int bucketIndex) {
- Entry<K,V> e = table[bucketIndex];
+ @SuppressWarnings("unchecked")
+ Entry<K,V> e = (Entry<K,V>)table[bucketIndex];
table[bucketIndex] = new Entry<>(hash, key, value, e);
size++;
}
private abstract class HashIterator<E> implements Iterator<E> {
- Entry<K,V> next; // next entry to return
+ Entry<?,?> next; // next entry to return
int expectedModCount; // For fast-fail
int index; // current slot
- Entry<K,V> current; // current entry
+ Entry<?,?> current; // current entry
HashIterator() {
expectedModCount = modCount;
if (size > 0) { // advance to first entry
- Entry[] t = table;
+ Entry<?,?>[] t = table;
while (index < t.length && (next = t[index++]) == null)
;
}
}
public final boolean hasNext() {
return next != null;
}
+ @SuppressWarnings("unchecked")
final Entry<K,V> nextEntry() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
- Entry<K,V> e = next;
+ Entry<?,?> e = next;
if (e == null)
throw new NoSuchElementException();
if ((next = e.next) == null) {
- Entry[] t = table;
+ Entry<?,?>[] t = table;
while (index < t.length && (next = t[index++]) == null)
;
}
current = e;
- return e;
+ return (Entry<K,V>)e;
}
public void remove() {
if (current == null)
throw new IllegalStateException();
@@ -963,11 +975,11 @@
return newEntryIterator();
}
public boolean contains(Object o) {
if (!(o instanceof Map.Entry))
return false;
- Map.Entry<K,V> e = (Map.Entry<K,V>) o;
+ Map.Entry<?,?> e = (Map.Entry<?,?>) o;
Entry<K,V> candidate = getEntry(e.getKey());
return candidate != null && candidate.equals(e);
}
public boolean remove(Object o) {
return removeMapping(o) != null;
@@ -1037,11 +1049,13 @@
// 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++) {
+ @SuppressWarnings("unchecked")
K key = (K) s.readObject();
+ @SuppressWarnings("unchecked")
V value = (V) s.readObject();
putForCreate(key, value);
}
}