1 public class opendressinghash<Key, Value> { 2 private static final int INIT_CAPACITY = 4; 3 4 private int n; 5 private int m; 6 private Key[] keys; 7 private Value[] vals; 8 9 public opendressinghash() { 10 this(INIT_CAPACITY); 11 } 12 13 public opendressinghash(int capacity) { 14 m = capacity; 15 n = 0; 16 keys = (Key[]) new Object[m]; 17 vals = (Value[]) new Object[m]; 18 } 19 20 21 public int size() { 22 return n; 23 } 24 25 26 public boolean isEmpty() { 27 return size() == 0; 28 } 29 30 31 public boolean contains(Key key) { 32 if (key == null) throw new NullPointerException("argument to contains() is null"); 33 return get(key) != null; 34 } 35 36 37 private int hash(Key key) { 38 return (key.hashCode() & 0x7fffffff) % m; 39 } 40 41 42 private void resize(int capacity) { 43 opendressinghash<Key, Value> temp = new opendressinghash<Key, Value>(capacity); 44 for (int i = 0; i < m; i++) { 45 if (keys[i] != null) { 46 temp.put(keys[i], vals[i]); 47 } 48 } 49 keys = temp.keys; 50 vals = temp.vals; 51 m = temp.m; 52 } 53 54 55 public void put(Key key, Value val) { 56 if (key == null) throw new NullPointerException("first argument to put() is null"); 57 58 if (val == null) { 59 delete(key); 60 return; 61 } 62 63 64 if (n >= m/2) resize(2*m); 65 66 int i; 67 for (i = hash(key); keys[i] != null; i = (i + 1) % m) { 68 if (keys[i].equals(key)) { 69 vals[i] = val; 70 return; 71 } 72 } 73 keys[i] = key; 74 vals[i] = val; 75 n++; 76 } 77 78 public Value get(Key key) { 79 if (key == null) throw new NullPointerException("argument to get() is null"); 80 for (int i = hash(key); keys[i] != null; i = (i + 1) % m) 81 if (keys[i].equals(key)) 82 return vals[i]; 83 return null; 84 } 85 86 87 public void delete(Key key) { 88 if (key == null) throw new NullPointerException("argument to delete() is null"); 89 if (!contains(key)) return; 90 91 // find position i of key 92 int i = hash(key); 93 while (!key.equals(keys[i])) { 94 i = (i + 1) % m; 95 } 96 97 // delete key and associated value 98 keys[i] = null; 99 vals[i] = null; 100 101 // rehash all keys in same cluster 102 i = (i + 1) % m; 103 while (keys[i] != null) { 104 // delete keys[i] an vals[i] and reinsert 105 Key keyToRehash = keys[i]; 106 Value valToRehash = vals[i]; 107 keys[i] = null; 108 vals[i] = null; 109 n--; 110 put(keyToRehash, valToRehash); 111 i = (i + 1) % m; 112 } 113 114 n--; 115 116 // halves size of array if it‘s 12.5% full or less 117 if (n > 0 && n <= m/8) resize(m/2); 118 119 assert check(); 120 } 121 122 123 124 private boolean check() { 125 126 // check that hash table is at most 50% full 127 if (m < 2*n) { 128 System.err.println("Hash table size m = " + m + "; array size n = " + n); 129 return false; 130 } 131 132 // check that each key in table can be found by get() 133 for (int i = 0; i < m; i++) { 134 if (keys[i] == null) continue; 135 else if (get(keys[i]) != vals[i]) { 136 System.err.println("get[" + keys[i] + "] = " + get(keys[i]) + "; vals[i] = " + vals[i]); 137 return false; 138 } 139 } 140 return true; 141 } 142 143 144 145 146 }
时间: 2024-10-05 22:33:48