title: HashMap原理及实现
tags: [算法与数据结构,Java,HashMap]
categories: 算法与数据结构
table a = []
int index = hash(key)
int value = a[index]
key,找下标,有哪些方法可以找到下标
public interface Ihashmap<K,V> {
public V put(K k,V v);
public V get(K k);
public int size();
public interface Entry<K,V>{
public K getKey();
public V getValue();
}
}
import java.util.ArrayList;
import java.util.List;
public class hMap<K,V> implements Ihashmap<K,V> {
private static int defaultLength = 16;
//负载因子 超过defaultLength*defalutLoader Hasp必须扩容
private static double defalutLoader = 0.75;
private Entry<K,V> [] table = null;
private int size = 0;
public hMap(int length,double loader){
defalutLoader = loader;
defaultLength = length;
table = new Entry[defaultLength];
}
public hMap(){
this(defaultLength,defalutLoader);
}
public V put(K k,V v){
//在这里判断一下size是否达到扩容的标准
if(size >= defaultLength*defalutLoader){
up2size();
}
//1.创建一个hash函数,根据key和hash函数算出数组下标
int index = getIndex(k);
Entry<K,V> entry = table[index];
if (entry == null){
//如果entry为null,说明table的index位置没有元素
table[index] = newEntry(k,v,null);
size++;
}else{
//如果index位置不为空,说明index位置有元素,那么要进行一个替换,然后next指针指向老数据
table[index] = newEntry(k,v,entry);
}
return table[index].getValue();
}
private void up2size(){
Entry<K,V>[] newTable = new Entry[2*defaultLength];
//新创建的数组以后,以前老数组里面的元素要对新数组再进行散列
againHash(newTable);
}
private void againHash(Entry<K,V>[]newTable){
List<Entry<K,V>> list = new ArrayList<Entry<K, V>>();
for (int i=0;i<table.length;i++){
if(table[i] == null){
continue;
}
findEntryByNext(table[i],list);
}
if(list.size()>0){
//要进行一个数组的再散列
size = 0;
defaultLength = defaultLength * 2;
table = newTable;
for(Entry<K,V> entry:list){
if(entry.next != null){
entry.next = null;
}
put(entry.getKey(),entry.getValue());
}
}
}
private void findEntryByNext(Entry<K,V> entry,List<Entry<K,V>> list){
if(entry != null && entry.next != null){
list.add(entry);
findEntryByNext(entry.next,list);
}else{
list.add(entry);
}
}
private Entry<K,V> newEntry(K k,V v,Entry<K,V>next){
return new Entry(k,v,next);
}
private int getIndex(K k){
int m = defaultLength;
int index = k.hashCode()%m;
return index>=0 ? index:-index;
}
public V get(K k){
//1.创建一个hash函数,根据key和hash函数算出数组下标
int index = getIndex(k);
if (table[index] == null){
return null;
}
return findValueByEqualKey(k,table[index]);
}
public V findValueByEqualKey(K k,Entry<K,V> entry){
if(k == entry.getKey() || k.equals((entry.getKey()))){
return entry.getValue();
}else {
if (entry.next != null){
return findValueByEqualKey(k,entry.next);
}
}
return null;
}
public int size(){
return size;
}
class Entry<K,V> implements Ihashmap.Entry<K,V>{
K k;
V v;
Entry<K,V> next;
public Entry(K k,V v,Entry<K,V> next){
this.k = k;
this.v = v;
this.next = next;
}
public K getKey(){
return k;
}
public V getValue(){
return v;
}
}
}
import java.util.HashMap;
import java.util.Map;
/**
* Created by Administrator on 2017/6/15.
*/
public class Test {
public static void main(String[] args){
Ihashmap<String,String> lmap = new hMap<String,String>();
Long t1 = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
lmap.put("key"+i,"value"+i);
}
for (int i = 0; i < 1000; i++) {
System.out.println("key:"+"key"+i + " value:"+lmap.get("key"+i));
}
Long t2 = System.currentTimeMillis();
System.out.println("手写实现haspmap耗时:"+(t2-t1));
System.out.println("--------------hashMap--------------");
Map<String,String> map = new HashMap<String,String>();
Long t3 = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
lmap.put("key"+i,"value"+i);
}
for (int i = 0; i < 10000; i++) {
System.out.println("key:"+"key"+i + " value:"+lmap.get("key"+i));
}
Long t4 = System.currentTimeMillis();
System.out.println("JDK实现haspmap耗时:"+(t4-t3));
System.out.println("手写实现haspmap耗时:"+(t2-t1));
}
}
更多内容请关注微信公众号: