参考源码,实现了一个简单的HashMap。。。。。。
<span style="font-size:18px;">package test;
import java.util.Map;
import test.MyHashMap.Entry;
public class MyHashMap<K,V> {
private Entry[] table;//Entry数组表
static final int DEFAULT_INITIAL_CAPACITY = 16;//默认数组长度
private int size ;
// 构造函数
public MyHashMap() {
table = new Entry[DEFAULT_INITIAL_CAPACITY];
size = 0;
}
//获取数组长度
public int getSize() {
return size;
}
// 求index
static int indexFor(int h, int length) {
return h % (length - 1);
}
//数组中链表的节点元素
static class Entry<K,V>{
final long hash;
K key;
V value;
Entry<K,V> next;
Entry(K key,V value,long hash,Entry<K,V> next){
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
public final K getKey() {
return key;
}
public final V getValue() {
return value;
}
public final V setValue(V newValue) {
V oldValue = value;
value = newValue;
return oldValue;
}
public final boolean equals(Object o) {
if (!(o instanceof Map.Entry))
return false;
MyHashMap.Entry e = (Entry) o;
Object k1 = getKey();
Object k2 = e.getKey();
if (k1 == k2 || (k1 != null && k1.equals(k2))) {
Object v1 = getValue();
Object v2 = e.getValue();
if (v1 == v2 || (v1 != null && v1.equals(v2)))
return true;
}
return false;
}
public final int hashCode() {
return (key==null ? 0 : key.hashCode()) ^ (value==null ? 0 : value.hashCode());
}
public final String toString() {
return getKey() + "=" + getValue();
}
}
//获取元素
public V get(Object key) {
if (key == null)
return getForNullKey();
int hash = key.hashCode();// key的哈希值
int index = indexFor(hash, table.length);// 求key在数组中的下标
for (Entry<K, V> e = table[index]; e != null; e = e.next) {
Object k = e.key;
if (e.key.hashCode() == hash && (k == key || key.equals(k)))
return e.value;
}
return null;
}
//得到Key为null时的Value
private V getForNullKey() {
for (Entry<K,V> e = table[0]; e != null; e = e.next) {
if (e.key == null)
return e.value;
}
return null;
}
// 添加元素
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = key.hashCode();
int index = indexFor(hash, table.length);
// 如果添加的key已经存在,那么只需要修改value值即可
for (Entry<K, V> e = table[index]; e != null; e = e.next) {
Object k = e.key;
if (e.key.hashCode() == hash && (k == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
return oldValue;// 原来的value值
}
}
// 如果key值不存在,那么需要添加
Entry<K, V> e = table[index];// 获取当前数组中的e
table[index] = new Entry<K, V>(key, value,hash, e);// 新建一个Entry,并将其指向原先的e
size++;
return null;
}
//添加Key为null时的Value
private V putForNullKey(V value) {
for (Entry<K,V> e = table[0]; e != null; e = e.next) {
if (e.key == null) {
V oldValue = e.value;
e.value = value;
return oldValue;
}
}
size++;
Entry<K, V> e = table[0];// 获取当前数组中的e
table[0] = new Entry<K, V>(null, value,0, e);// 新建一个Entry,并将其指向原先的e
return null;
}
public V remove(Object key) {
int hash = (key == null) ? 0 : key.hashCode();
int i = indexFor(hash, table.length);
Entry<K,V> prev = table[i];
Entry<K,V> e = prev;
while (e != null) {
Entry<K,V> next = e.next;
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k)))) {
size--;
if (prev == e)
table[i] = next;
else
prev.next = next;
return e.value;
}
prev = e;
e = next;
}
return e.value;
}
}
</span>
测试代码:
<span style="font-size:18px;">package test;
public class MapTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
MyHashMap<Integer, Integer> map = new MyHashMap<Integer, Integer>();
map.put(11, 92);
map.put(33, 25);
map.put(17, 35);
map.put(null, 45);
System.out.println(map.get(11));
System.out.println(map.get(33));
System.out.println(map.remove(17));
System.out.println(map.get(null));
System.out.println(map.getSize());
}
}
</span>
输出结果:
92
25
35
45
3
上面的代码写的还是比较粗糙的是,只是实现了HashMap中的get,put,remove三个功能,table长度是固定的16,也没有对Key的hashcode进行hash处理。。。。。
通过阅读源代码确实是一种很好的学习方式,不可以学习作者的编程思想,还能规范自己的编码习惯,尤其很多细节的东西细细品味真是回味无穷,不得不由衷的感叹一句,真的是大神啊。。。。