自己实现一个简单的hashmap
这个hashmap实现方式应该是jdk1.7的,在数据量小的时候和jdk1.8实现的差不多,不过我这个没有采用链表长度8时转化红黑树增加查询效率,在扩容时也是全部元素重新hash,计算新的位置,
所以如果大数据量的时候,复制到新的数组就会比较慢.,jdk8里面对复制到新的数组也是有优化的,我这里就没做了.
1 package com.tqq; 2 3 /** 4 * @Description: 自己实现简易hashmap,只有put和get,会自动扩容,没有链表达到长度转红黑树 5 * @Author: Tan 6 * @CreateDate: 2020/3/15 7 **/ 8 public class MyHashMap<K,V> { 9 10 //节点数组 用于存放所有节点 11 Node[] NodeArray; 12 //节点数组默认大小 13 int defaultSize=16; 14 15 int NodeCount=0; 16 17 //链表 18 class Node<K,V> { 19 int hash; 20 K key; 21 V value; 22 Node nextNode; 23 public Node(int hash, K key, V value, Node nextNode) { 24 this.hash = hash; 25 this.key = key; 26 this.value = value; 27 this.nextNode = nextNode; 28 } 29 30 public Node() { 31 } 32 } 33 34 35 36 public V put(K key,V value){ 37 V returnValue=null; 38 if(NodeArray==null){ 39 NodeArray=new Node[defaultSize]; 40 } 41 //得到当前key存放于节点数组中的索引 42 int nodeArrayIndex=(key.hashCode())%NodeArray.length; 43 44 nodeArrayIndex=Math.abs(nodeArrayIndex); 45 Node indexNode=NodeArray[nodeArrayIndex]; 46 if(indexNode==null){ 47 NodeArray[nodeArrayIndex]=new Node(key.hashCode(),key,value,null); 48 returnValue=value; 49 }else{ 50 Node next=indexNode; 51 while (true){ 52 if(key.equals(next.key)){ 53 next.value=value; 54 next.hash=key.hashCode(); 55 returnValue=value; 56 break; 57 } 58 if(next.nextNode==null){ 59 next.nextNode=new Node(key.hashCode(),key,value,null); 60 returnValue=value; 61 break; 62 } 63 next=next.nextNode; 64 } 65 } 66 NodeCount++; 67 resize(); 68 return returnValue; 69 } 70 71 72 public V get(K key){ 73 //得到当前key存放于节点数组中的索引 74 int nodeArrayIndex=(key.hashCode())%defaultSize; 75 if (NodeArray!=null){ 76 Node indexNode= NodeArray[nodeArrayIndex]; 77 if(indexNode.hash==key.hashCode()&&key==indexNode.key){ 78 return (V) indexNode.value; 79 } 80 while ((indexNode=indexNode.nextNode)!=null){ 81 if(indexNode.hash==key.hashCode()&&key==indexNode.key){ 82 return (V) indexNode.value; 83 } 84 } 85 } 86 return null; 87 } 88 89 90 public void resize(){ 91 if(NodeCount>=NodeArray.length*0.75){ 92 Node[] newNodeArray=new Node[NodeArray.length*2]; 93 for (int i = 0; i < NodeArray.length; i++) { 94 if(NodeArray[i]!=null){ 95 NodeMove(NodeArray[i],newNodeArray); 96 while (NodeArray[i].nextNode!=null){ 97 NodeMove(NodeArray[i].nextNode,newNodeArray); 98 NodeArray[i]=NodeArray[i].nextNode; 99 } 100 } 101 } 102 NodeArray=newNodeArray; 103 } 104 } 105 106 //移动 107 public void NodeMove(Node node,Node[] newNodeArray){ 108 int nodeArrayIndex=Math.abs((node.key.hashCode())%newNodeArray.length); 109 if(newNodeArray[nodeArrayIndex]==null){ 110 newNodeArray[nodeArrayIndex]=node; 111 }else{ 112 Node next=newNodeArray[nodeArrayIndex]; 113 while (true){ 114 if(node.key.equals(next.key)){ 115 next.value=node.value; 116 next.hash=node.key.hashCode(); 117 break; 118 } 119 if(next.nextNode==null){ 120 next.nextNode=new Node(node.hashCode(),node.key,node.value,null); 121 break; 122 } 123 next=next.nextNode; 124 } 125 } 126 } 127 128 129 }