HashMap模拟
HashMap继承自Map类,无序不可重。
他的使用方法很多博客都写了,我就写一个模拟HashMap的类。
HashMap底层是由数组和链表构造的。
Map有键值同时存储,用键找值,键不可重复的特性。我们可以简单的想一个办法,把键值对以对象的方式存储到数组中,取出的时候再通过遍历和get方法获得值。
但是这样有一个缺陷:每次取值都要遍历整个数组并作比较,非常复杂。
所以HashMap做出了这样的改进:对每一个对象取HashCode值并对数组的长度取余,把得到的值作为数组下标,这样在取值的时候就可以直接通过传入的对象的HashCode获取下标,大大简化了计算。
但是这样还有一个问题:HashCode对数组长度取余可能有重复。
所以引入链表,相同的取余值存入到链表中,在取值的时候就可以通过HashCode找到下标,再遍历对应的链表,这样依然大大简化了步骤。
就是在数组中存储链表。
1 package Map; 2 3 import java.util.LinkedList; 4 5 public class FinalMap { 6 int size; 7 LinkedList[] map = new LinkedList[999];//链表数组 8 public FinalMap(){ 9 10 } 11 /* 12 * 添加的方法 13 * */ 14 public boolean add(Object key, Object value){ 15 int hashCode = key.hashCode(); 16 int index = hashCode % map.length; 17 if(map[index] == null){//如果初试值为null,就添加一个新的链表。 18 LinkedList ll = new LinkedList(); 19 ll.add(new Node(key, value)); 20 map[index] = ll; 21 }else{//如果不为空,则先判断键是否重复。若是,则替换值;若否,则直接添加信息。 22 for(Object o : map[index]) 23 if(((Node)o).getKey().equals(key)) 24 ((Node)o).setValue(value); 25 else 26 map[index].add(new Object()); 27 } 28 return true; 29 } 30 /* 31 * 取值的方法 32 * */ 33 public Object get(Object key){ 34 int hashCode = key.hashCode(); 35 int index = hashCode % map.length; 36 for(Object o : map[index]) 37 if(((Node)o).getKey().equals(key)) 38 return ((Node)o).getValue(); 39 return null; 40 } 41 } 42 /* 43 * 存储的基本单元类 44 * */ 45 class Node{ 46 Object key; 47 Object value; 48 public Object getKey() { 49 return key; 50 } 51 public void setKey(Object key) { 52 this.key = key; 53 } 54 public Object getValue() { 55 return value; 56 } 57 public void setValue(Object value) { 58 this.value = value; 59 } 60 public Node(Object key, Object value) { 61 this.key = key; 62 this.value = value; 63 } 64 65 }