fix: support null keys with occupied slots
This commit is contained in:
@@ -6,12 +6,14 @@ public class MyHashMap<Key, Value> {
|
|||||||
|
|
||||||
private Key[] keys;
|
private Key[] keys;
|
||||||
private Value[] values;
|
private Value[] values;
|
||||||
|
private boolean[] occupied;
|
||||||
private boolean[] deleted;
|
private boolean[] deleted;
|
||||||
private int size;
|
private int size;
|
||||||
|
|
||||||
public MyHashMap(int capacity) {
|
public MyHashMap(int capacity) {
|
||||||
keys = createArray(capacity);
|
keys = createArray(capacity);
|
||||||
values = createArray(capacity);
|
values = createArray(capacity);
|
||||||
|
occupied = new boolean[capacity];
|
||||||
deleted = new boolean[capacity];
|
deleted = new boolean[capacity];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,26 +28,19 @@ public class MyHashMap<Key, Value> {
|
|||||||
resize();
|
resize();
|
||||||
}
|
}
|
||||||
|
|
||||||
int index = index(key);
|
int index = findIndex(key);
|
||||||
int start = index;
|
|
||||||
|
|
||||||
while (keys[index] != null || deleted[index]) {
|
if (index != -1) {
|
||||||
if (!deleted[index] && Objects.equals(keys[index], key)) {
|
Value oldValue = values[index];
|
||||||
Value oldValue = values[index];
|
values[index] = value;
|
||||||
values[index] = value;
|
return oldValue;
|
||||||
return oldValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
index = (index + 1) % keys.length;
|
|
||||||
|
|
||||||
if (index == start) {
|
|
||||||
resize();
|
|
||||||
return put(key, value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
index = findEmptyIndex(key);
|
||||||
|
|
||||||
keys[index] = key;
|
keys[index] = key;
|
||||||
values[index] = value;
|
values[index] = value;
|
||||||
|
occupied[index] = true;
|
||||||
deleted[index] = false;
|
deleted[index] = false;
|
||||||
size++;
|
size++;
|
||||||
|
|
||||||
@@ -60,6 +55,7 @@ public class MyHashMap<Key, Value> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Value oldValue = values[index];
|
Value oldValue = values[index];
|
||||||
|
occupied[index] = false;
|
||||||
deleted[index] = true;
|
deleted[index] = true;
|
||||||
size--;
|
size--;
|
||||||
|
|
||||||
@@ -70,8 +66,8 @@ public class MyHashMap<Key, Value> {
|
|||||||
int index = index(key);
|
int index = index(key);
|
||||||
int start = index;
|
int start = index;
|
||||||
|
|
||||||
while (keys[index] != null || deleted[index]) {
|
while (occupied[index] || deleted[index]) {
|
||||||
if (!deleted[index] && Objects.equals(keys[index], key)) {
|
if (occupied[index] && Objects.equals(keys[index], key)) {
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,22 +81,43 @@ public class MyHashMap<Key, Value> {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int findEmptyIndex(Key key) {
|
||||||
|
int index = index(key);
|
||||||
|
int start = index;
|
||||||
|
int deletedIndex = -1;
|
||||||
|
|
||||||
|
while (occupied[index]) {
|
||||||
|
if (Objects.equals(keys[index], key)) {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
index = (index + 1) % keys.length;
|
||||||
|
|
||||||
|
if (index == start) {
|
||||||
|
return deletedIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return deletedIndex == -1 ? index : deletedIndex;
|
||||||
|
}
|
||||||
|
|
||||||
private int index(Key key) {
|
private int index(Key key) {
|
||||||
return Math.floorMod(key.hashCode(), keys.length);
|
return Math.floorMod(key == null ? 0 : key.hashCode(), keys.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resize() {
|
private void resize() {
|
||||||
Key[] oldKeys = keys;
|
Key[] oldKeys = keys;
|
||||||
Value[] oldValues = values;
|
Value[] oldValues = values;
|
||||||
boolean[] oldDeleted = deleted;
|
boolean[] oldOccupied = occupied;
|
||||||
|
|
||||||
keys = createArray(oldKeys.length * 2);
|
keys = createArray(oldKeys.length * 2);
|
||||||
values = createArray(oldValues.length * 2);
|
values = createArray(oldValues.length * 2);
|
||||||
|
occupied = new boolean[keys.length];
|
||||||
deleted = new boolean[keys.length];
|
deleted = new boolean[keys.length];
|
||||||
size = 0;
|
size = 0;
|
||||||
|
|
||||||
for (int i = 0; i < oldKeys.length; i++) {
|
for (int i = 0; i < oldKeys.length; i++) {
|
||||||
if (oldKeys[i] != null && !oldDeleted[i]) {
|
if (oldOccupied[i]) {
|
||||||
put(oldKeys[i], oldValues[i]);
|
put(oldKeys[i], oldValues[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user