1、接口
package com.zhuzhu.map;
/**
* <p>Title: ZhuzhuMap</p>
* <p>Description: </p>
* @author zhuzhu
* @date 2018年8月13日
*/
public interface ZhuzhuMap<K,V> {
/**
* 向集合中插入元素
*/
public V put(K k,V v);
/**
* 根据k 从Map中查询元素
*/
public V get(K k);
/**
* 获取元素个数
*/
public int size();
/**
* 判断是否为空
*/
public boolean isEmpty();
/**
* 打印Map
*/
public void printMap();
interface Entry<K,V>{
K getKey();
V getValue();
}
}
2、接口实现类
package com.zhuzhu.map;
import java.util.ArrayList;
import java.util.List;
public class ZhuzhuHashMap<K,V> implements ZhuzhuMap<K,V> {
/**
* 自定义hash表 table,懒加载功能
*/
Node<K,V>[] table=null;
/**
* 实际 key value 键值对的数量
*/
int size;
/**
* HashMap默认负载因子,负载因子越小,hash冲突率越低
*/
float DEFAULT_LOAD_FACTORY=0.75f;
/**
* table默认初始化大小
*/
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;
@Override
public V put(K k, V v) {
//1、判断table数组大小是否为空 如果为空 初始化
if(table==null) {
table =new Node[DEFAULT_INITIAL_CAPACITY];
}
//2、判断数组是否需要扩容
if(size>DEFAULT_LOAD_FACTORY*table.length) {
resize();
}
//3、计算hash值指定下标位置 index,key的hash值与2^n进行与运算 使数组广泛
int index=k.hashCode()&(table.length-1);
//4、判断是否发生hash冲突
if(table[index]==null) {
//没有发生hash冲突
table[index]=new Node<K,V>(k, v, null);
size++;
}else {
//懒加载
Node<K,V> node = null;
if(table[index].getKey().equals(k) || table[index].getKey()==k){
//已经发生hash冲突,修改value
V oldValue=table[index].getValue();
table[index].value=v;
return oldValue;
}else {
node=table[index];
while(true) {
//判断next是否为空
if(node.next==null) {
node.next=new Node<K,V>(k, v, null);
size++;
break;
}
//移动链表
node=node.next;
//存在冲突
if(node.getKey().equals(k) || node.getKey()==k) {
V oldValue=node.getValue();
node.value=v;
return oldValue;
}
}
}
}
return null;
}
private void resize() {
//扩容2倍
int newLength=table.length<<1;
Node<K,V>[] newTable=new Node[newLength];
//存储所有key value键值对 暴力扩容
List<Node<K,V>> listNode=null;
for(int i=0;i<table.length;i++) {
if(table[i]==null) {
continue;
}else {
Node<K,V> node=table[i];
table[i]=null;
//更新Table
while(node!=null) {
if(listNode==null) {
listNode=new ArrayList<>();
}
listNode.add(node);
node=node.next;
}
}
}
//更新
size=0;
table=newTable;
for(Node<K,V> n:listNode) {
put(n.getKey(),n.getValue());
}
}
@Override
public void printMap() {
for(int i=0;i<table.length;i++) {
if(table[i]!=null) {
Node<K,V> node=table[i];
while(node!=null) {
System.out.println("index="+i+" "+node.getKey()+"--->"+node.getValue());
node=node.next;
}
}
}
}
@Override
public V get(K k) {
int index=k.hashCode()&(table.length-1);
if( table[index]==null || index>table.length) {
return null;
}else {
Node<K,V> node=table[index];
while(node!=null) {
if(node.getKey()==k || node.getKey().equals(k)) {
return node.value;
}
node=node.next;
}
}
return null;
}
@Override
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return size==0;
}
/**
* 定义节点
*/
class Node<K,V> implements Entry<K,V>{
//存放Map集合的Key
private K key;
//存放Map 集合 value
private V value;
//下一个节点Node
private Node<K,V> next;
public Node(K key,V value,Node<K,V> next){
this.key=key;
this.value=value;
this.next=next;
}
@Override
public K getKey() {
return this.key;
}
@Override
public V getValue() {
return this.value;
}
}
}