@Java 300 學習總結
HashMap底層采用實現采用了哈希表,結合了“數組和鏈表”。
原理如圖
一、定義HashMap類。
首先需要定義一個節點來存儲數據,構成鏈表結構。
public class Node {
int hash;
Object key;
Object value;
Node next;
}
public class ggHashMap {
Node[] table; //位桶數組,用於存放鏈表的第一個節點
int size;
public ggHashMap() {
super();
table = new Node[16]; //默認初始為16
}
public static void main(String[] args) {
ggHashMap m1 = new ggHashMap();
System.out.println();
}
}
二、實現put方法,往HashMap里添加元素
每一個節點存放進HashMap里,首先根據key繼續Hash值,以此確定插入的位置。
public int myHash(int v,int length) {
return v&(length -1);//根據Hash值與位桶數組長度,進行位運算,保證插入元素的隨機
//位運算與取模運算效果相同,但是效率更高
}
public void put(Object key, Object value) {
Node newNode = new Node();
newNode.hash = myHash(key.hashCode(),table.length);
//根據key的值取hash值,hashCode()為對象默認存在的方法
newNode.key = key;
newNode.value = value;
newNode.next = null;
Node temp = table[newNode.hash];//指向要插入的數組位置
Node iterLast = null;//正在遍歷的最后一個元素
boolean keyRepeat = false;//判定元素key值是否相同被覆蓋
if(temp == null) { //數組元素為空
table[newNode.hash] = newNode;
}
else { //不為空的情況
while(temp!=null) { //遍歷該鏈表
//判斷key是否重復
if(temp.key.equals(key)) {
keyRepeat = true;
temp.value = value;
break; //找到重復結束遍歷
}else {
iterLast = temp; //iterLast跟着temp向后移一位
temp = temp.next;
}
}
if(!keyRepeat) {
iterLast.next = newNode; //沒有發現重復,最后一位的next,指向新節點
}
}
}
三、實現toString方法
利用可以自動擴增的StringBuilder對象,遍歷每個節點,可實現數據的HashMap的字符串。
public String toString() {
StringBuilder sb = new StringBuilder("{");
for(int i = 0;i < table.length;i++) {
Node temp = table[i];
while(temp!=null) {
sb.append(temp.key+":"+temp.value + ",");
temp = temp.next;
}
}
sb.setCharAt(sb.length()-1, '}');//將最后一個,號,轉為}
return sb.toString();
}
四、實現get方法,根據key獲得value
根據key值計算hash數值,指針指向數組索引值和hash值相等的節點,遍歷該節點的鏈表,找到key值相等的節點,返回value值
public Object get(Object key) {
int hash = myHash(key.hashCode(), table.length);
Object value = null;
Node temp = table[hash];
while(temp!=null) {
if(temp.key.equals(key)) {
value = temp.value;
break;
}else {
temp = temp.next;
}
}
return value;
}
五、增加泛型
public class Node2<K,V> {
int hash;
K key;
V value;
Node2 next;
}
public class ggHashMap4<K,V> {
public V get(K key) {
}
public void put(K key, V value) {
}
}