Map-hashMap实现原理

实现思路:

1.利用一维数组中存放双向链表来时间,同一组链表中存放hash值相同的数据(解决hash冲突)。

2.根据hash因子(扩容数组的倍数,默认0.75)来扩展其容量,每次扩展后要将之前存放的数据重新计算hash值,进行重新排列(所以hashMap是无序的)。

git上项目路径: https://github.com/0ziyu0/handWriting

代码

接口:

 1 public interface CustomerCapacityExpansionHashMap<Key, Value> {
 2     
 3     void put(Key key, Value value);
 4     
 5     Value get(Key key);
 6     
 7     Value remove(Key key);
 8     
 9     Integer size();
10     
11     public void print();
12 
13     interface Entity<Key, Value> {
14         
15         Key getKey();
16         // 设置新的值,返回修改之前的值
17         Value setValue(Value value);
18         Value getValue();
19     }
20 
21 }

实现:

  1 public class CapacityExpansionHashMap<Key, Value> implements CustomerCapacityExpansionHashMap<Key, Value> {
  2 
  3     private Node<Key, Value>[] nodeArray = null;
  4     int size = 0;
  5     float DEFAULT_LOAD_FACTOR = 0.75f;
  6     // 初始容量
  7     static int DEFAULT_INITIAL_CAPACITY = 2;
  8 
  9     @Override
 10     public void put(Key key, Value value) {
 11 
 12         if(nodeArray == null) {
 13             nodeArray = new Node[DEFAULT_INITIAL_CAPACITY];
 14         }
 15         if(size >= DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR) {
 16             resize();
 17         }
 18         Integer hashCode = getHashCode(key, DEFAULT_INITIAL_CAPACITY);
 19         Node<Key, Value> node = nodeArray[hashCode];
 20         if(node == null) {//直接保存
 21             node = new Node<Key, Value>(key, value, null);
 22             size++;
 23         } else {
 24             Node<Key, Value> newNode = node;
 25             while(newNode != null) {
 26                 if(newNode.getKey().equals(key) || newNode.getKey()== key) {
 27                     newNode.setValue(value);
 28                 } else {
 29                     if(newNode.nextNode == null) {//没有后续节点
 30                         node = new Node<Key, Value>(key, value, node);
 31                         ++size;break;
 32                     }
 33                 }
 34                 newNode = newNode.nextNode;
 35             }
 36         }
 37         nodeArray[hashCode] = node;
 38     }
 39 
 40     @Override
 41     public Value get(Key key) {
 42 
 43         Value resultValue = null;
 44         Node<Key, Value> node = getNode(key);
 45         if(node != null) {
 46             resultValue = node.value; 
 47         }
 48 
 49         return resultValue;
 50     }
 51 
 52     @Override
 53     public Value remove(Key key) {
 54 
 55         Value oldeValue = null;
 56         Integer hashCode = getHashCode(key, nodeArray.length);
 57         Node<Key, Value> node = nodeArray[hashCode];
 58         Node<Key, Value> oldeNode = null;
 59         while(node != null) {
 60             if(node.getKey().equals(key)) {
 61                 oldeValue = node.getValue();
 62                 if(oldeNode != null) {
 63                     oldeNode.nextNode = node.nextNode;
 64                     node = null;
 65                 } else {
 66                     nodeArray[hashCode] = null;
 67                 }
 68                 
 69                 --size;
 70                 break;
 71             }
 72             oldeNode = node;
 73             node = node.nextNode;
 74         }
 75         
 76         return oldeValue;
 77     }
 78 
 79     @Override
 80     public Integer size() {
 81 
 82         return size;
 83     }
 84 
 85     private Node<Key, Value> getNode(Key key) {
 86 
 87         Integer hashCode = getHashCode(key, nodeArray.length);
 88         Node<Key, Value> oldNode = nodeArray[hashCode];
 89         while(oldNode != null) {
 90             if(oldNode.getKey().equals(key)) {
 91                 return oldNode;
 92             }
 93             oldNode = oldNode.nextNode;
 94         }
 95 
 96         return null;
 97     }
 98 
 99     private void resize() {
100 
101         Node<Key, Value>[] newNodeArray = new Node[DEFAULT_INITIAL_CAPACITY << 1];
102         Integer hashCode = null;
103         for (int i = 0; i < nodeArray.length; i++) {
104             Node<Key, Value> oldNode = nodeArray[i];
105             // 重新计算之前node节点的hash值将其存放到新节点中
106             while (oldNode != null) {
107                 hashCode = getHashCode(oldNode.getKey(), newNodeArray.length);
108                 Node<Key, Value> oldNext = oldNode.nextNode;
109                 oldNode.nextNode = newNodeArray[hashCode];
110                 newNodeArray[hashCode] = oldNode;
111                 // 继续循环
112                 oldNode = oldNext;
113             }
114         }
115         nodeArray = newNodeArray;
116         DEFAULT_INITIAL_CAPACITY = newNodeArray.length;
117         newNodeArray = null;
118     }
119 
120     private    Integer getHashCode(Key key, Integer length) {
121         if(key == null) {
122             return 0;
123         }
124         return key.hashCode() % length;
125     }
126     
127     public void print() {
128         System.out.println("size:" + size);
129         for (int i = 0; i < nodeArray.length; i++ ) {
130             Node<Key, Value> node = nodeArray[i];
131             while(node != null) {
132                 System.out.println("key: " + node.getKey() + "  value:  " +node.getValue());
133                 node = node.nextNode;
134             }
135         }
136     }
137     
138     class Node<Key, Value> implements Entity<Key, Value> {
139 
140         private Key key;
141         private Value value;
142         private Node<Key, Value> nextNode;
143 
144         public Node(Key key, Value value, Node<Key, Value> nextNode) {
145             super();
146             this.key = key;
147             this.value = value;
148             this.nextNode = nextNode;
149         }
150 
151         @Override
152         public Key getKey() {
153 
154             return this.key;
155         }
156 
157         @Override
158         public Value setValue(Value value) {
159             Value oldValue = this.value;
160             this.value = value;
161             return oldValue;
162         }
163 
164         @Override
165         public Value getValue() {
166 
167             return this.value;
168         }
169 
170     }
171 
172 }

测试代码:

 1 public class HashMapTest1 {
 2     
 3     @Test
 4     public void testPut001() {
 5         
 6         CustomerMap<String, String> map = new CustomerHashMap<String, String>();
 7         map.put("1", "001");
 8         System.out.println(map.size());
 9         map.print();
10         
11     }
12     
13     @Test
14     public void testPut002() {
15         
16         CustomerMap<String, String> map = new CustomerHashMap<String, String>();
17         map.put("1", "001");
18         map.put("2", "002");
19         map.put("1", "001");
20         System.out.println(map.size());
21         map.print();
22         
23     }
24     
25     @Test
26     public void testGet001() {
27         
28         CustomerMap<String, String> map = new CustomerHashMap<String, String>();
29         map.put("1", "001");
30         map.put("2", "002");
31         map.put("1", "001");
32         System.out.println(map.size());
33         map.print();
34         
35     }
36     
37     @Test
38     public void testRemore001() {
39         
40         CustomerMap<String, String> map = new CustomerHashMap<String, String>();
41         map.put("1", "001");
42         map.put("2", "002");
43         map.put("3", "003");
44         System.out.println(map.size());
45         map.print();
46         System.out.println("==================");
47         map.remove("1");
48         System.out.println(map.size());
49         map.print();
50         
51     }
52     
53     @Test
54     public void testRemore002() {
55         
56         CustomerMap<String, String> map = new CustomerHashMap<String, String>();
57         map.put("1", "001");
58         System.out.println(map.size());
59         map.print();
60         map.remove("11");
61         System.out.println("==================");
62         System.out.println(map.size());
63         map.print();
64         
65     }
66 }

运行截图:

 

posted @ 2019-01-16 21:41  东隅已逝x  Views(115)  Comments(0)    收藏  举报