public interface ExtMap<K, V> {
// 向集合中插入数据
public V put(K k, V v);
// 根据k 从Map集合中查询元素
public V get(K k);
// 获取集合元素个数
public int size();
interface Entry<K, V> {
K getKey();
V getValue();
V setValue(V value);
}
import com.mayikt.jdk7hash.ExtMap.Entry;
/**
* 手写jdk1.7的hashMap
*
* @author zjmiec
*
*/
public class ExtJdk7HaspMap<K, V> implements ExtMap<K, V> {
// 1.定义table 存放HashMap 数组元素 默认不初始化容器 拦截在
Node<K, V>[] table = null;
// 2.实际用到table 存储容量大小
int size;
/**
* 3.默认负载因子 0.75 扩容用到,负载因子越小。hash冲突几率越低, 根据每个链表个数
*/
float DEFAULT_LOAD_FACTOR = 0.75f;
// 4.table 默认初始大小 16
int DEFAULT_INITIAL_CAPACITY = 16;
public V put(K k, V v) {
// 1.判断table数组大小是否为空(如果为空,做初始化操作)
if (table == null) {
table = new Node[DEFAULT_INITIAL_CAPACITY];
}
/**
* 2.判断数组 是否需要扩容 为什么需要扩容? 使用链表查询,链表越长,查询效率越慢,而且, 数组存储采用hash下标,
* 过短会导致hash冲突的几率增加 如果size大于12,进行扩容数组,大小为之前的两倍
*/
if (size > DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY) {
// 开始对数组扩容
}
// 3.计算hash制定下标
int index = getIndex(k, DEFAULT_INITIAL_CAPACITY);
Node<K, V> node = table[index];
if (node == null) {
// 没有hash冲突
node = new Node<K, V>(k, v, null);
size++;
// return node.setValue(v);
} else {
Node<K, V> newNode = node;
// 發生hash冲突key 直接添加(冲突node)到前面了,不是往后加
while (newNode != null) {
if (newNode.getKey().equals(k) || newNode.getKey() == k) {
// hash相同,而且equals相同 说明是同一个对象,进行修改值
// node.value=v;
return newNode.setValue(v);
} else {
// 继续添加 排在前面hashCode 取模余数相同存
if (newNode.next == null) {
// 遍历node到最后没有存在相同的key,就会添加node
node = new Node<K, V>(k, v, node);
size++;
}
}
newNode = newNode.next;
}
}
table[index] = node;
return null;
}
private void resize() {
// 1.生成新的table,长度为之前的两倍
Node<K, V>[] newTable = new Node[DEFAULT_INITIAL_CAPACITY << 1];
// 2.重新计算index的索引,存放到新的table容器
for (int i = 0; i < table.length; i++) {
Node<K, V> oldNode = table[i];
while (oldNode != null) {
table[i] = null;// 垃圾回收
// 获取之前的key
K oldkey = oldNode.key;
// 重新计算index
int index = getIndex(oldkey, newTable.length);
// 存放在之前的table 原来的node next
ExtJdk7HaspMap<K, V>.Node<K, V> next = oldNode.next;
// 如果index在newTablez发生冲突,以链表方式存储
// 原来链表存放的是A,B,C,新链表会存储为C,B,A
// 原来node存放新node的下一个节点
oldNode.next = newTable[index];
// 将之前的node赋值给newTable[index]
newTable[index] = oldNode;
//
oldNode = next;
}
}
// 3.将新的table的赋值给旧的table
table = newTable;
DEFAULT_INITIAL_CAPACITY = newTable.length;
newTable = null;
}
void print() {
System.out.println("-------" + table.length);
for (int i = 0; i < table.length; i++) {
Node<K, V> node = table[i];
System.out.print("下标位置:" + i);
while (node != null) {
System.out.print("[ key:" + node.getKey() + ",value:" + node.getValue() + "]");
node = node.next;
/*
* if(node.next!=null){ node=node.next; }else{ node=null; }
*/
}
System.out.println();
}
}
public V get(K k) {
int index = getIndex(k, DEFAULT_INITIAL_CAPACITY);
Node<K, V> node = getNode(table[getIndex(k, DEFAULT_INITIAL_CAPACITY)], k);
return node == null ? null : node.value;
}
public Node<K, V> getNode(Node<K, V> node, K k) {
while (node.next != null) {
if (node.getKey().equals(k)) {
return node;
}
node = node.next;
}
return null;
}
public int size() {
// TODO Auto-generated method stub
return 0;
}
public int getIndex(K k, int length) {
int hashCode = k.hashCode();
int hash = hashCode % table.length;
return hash;
}
class Node<K, V> implements Entry<K, V> {
// 存放Map 集合key
private K key;
// 存放map 集合value
private V value;
private Node<K, V> next;
public K getKey() {
return this.key;
}
public Node(K key, V value, Node<K, V> next) {
super();
this.key = key;
this.value = value;
this.next = next;
}
public V getValue() {
// TODO Auto-generated method stub
return this.value;
}
public V setValue(V value) {
// 设置新值 返回老值
V oldValue = this.value;
this.value = value;
return oldValue;
}
}
}