diff --git a/src/main/java/core/basesyntax/MyHashMap.java b/src/main/java/core/basesyntax/MyHashMap.java index d9beffedf..655956743 100644 --- a/src/main/java/core/basesyntax/MyHashMap.java +++ b/src/main/java/core/basesyntax/MyHashMap.java @@ -1,19 +1,98 @@ package core.basesyntax; public class MyHashMap implements MyMap { + private static final int DEFAULT_CAPACITY = 16; + private static final double LOAD_FACTOR = 0.75; + private static final int RESIZE_MULTIPLIER = 2; + + private Node[] table; + private int size; + + public MyHashMap() { + table = (Node[]) new Node[DEFAULT_CAPACITY]; + } @Override public void put(K key, V value) { + if ((size + 1) > table.length * LOAD_FACTOR) { + resize(); + } + + int index = getIndex(key, table.length); + Node current = table[index]; + + while (current != null) { + if (keysAreEqual(current.key, key)) { + current.value = value; + return; + } + current = current.next; + } + Node newNode = new Node<>(key, value); + newNode.next = table[index]; + table[index] = newNode; + size++; } @Override public V getValue(K key) { + int index = getIndex(key, table.length); + Node current = table[index]; + + while (current != null) { + if (keysAreEqual(current.key, key)) { + return current.value; + } + current = current.next; + } + return null; } @Override public int getSize() { - return 0; + return size; + } + + private void resize() { + Node[] oldTable = table; + table = (Node[]) new Node[oldTable.length * RESIZE_MULTIPLIER]; + size = 0; + + for (Node node : oldTable) { + while (node != null) { + put(node.key, node.value); + node = node.next; + } + } + } + + private int getIndex(K key, int length) { + if (key == null) { + return 0; + } + return Math.abs(key.hashCode()) % length; + } + + private boolean keysAreEqual(K firstKey, K secondKey) { + if (firstKey == null && secondKey == null) { + return true; + } + if (firstKey == null || secondKey == null) { + return false; + } + return firstKey.equals(secondKey); + } + + private class Node { + private V value; + private K key; + private Node next; + + private Node(K key, V value) { + this.key = key; + this.value = value; + } } }