diff --git a/src/main/java/core/basesyntax/MyHashMap.java b/src/main/java/core/basesyntax/MyHashMap.java index d9beffedf..46f3c9901 100644 --- a/src/main/java/core/basesyntax/MyHashMap.java +++ b/src/main/java/core/basesyntax/MyHashMap.java @@ -1,19 +1,100 @@ package core.basesyntax; +import java.util.Objects; + public class MyHashMap implements MyMap { + private static final int DEFAULT_CAPACITY = 16; + private static final double LOAD_FACTOR = 0.75; + private int size; + private int capacity; + private int threshold; + private Node[] buckets; + + public MyHashMap() { + capacity = DEFAULT_CAPACITY; + threshold = (int) (LOAD_FACTOR * capacity); + buckets = (Node[]) new Node[capacity]; + } @Override public void put(K key, V value) { + checkSize(); + Node newNode = new Node<>(key, value); + int index = getIndex(key); + insertNode(newNode, index); } @Override public V getValue(K key) { - return null; + int index = getIndex(key); + Node bucket = buckets[index]; + while (bucket != null && !Objects.equals(bucket.key, key)) { + bucket = bucket.next; + } + return bucket != null ? bucket.value : null; } @Override public int getSize() { - return 0; + return size; + } + + private void checkSize() { + if (size >= threshold) { + resize(); + } + } + + private void resize() { + capacity *= 2; + threshold = (int) (LOAD_FACTOR * capacity); + size = 0; + Node[] oldCopy = buckets; + buckets = (Node[]) new Node[capacity]; + for (Node node : oldCopy) { + while (node != null) { + Node next = node.next; + node.next = null; + insertNode(node, getIndex(node.key)); + node = next; + } + } + } + + private int getIndex(K key) { + return (key == null) ? 0 : (key.hashCode() & Integer.MAX_VALUE) % capacity; + } + + private void insertNode(Node newNode, int index) { + Node bucket = buckets[index]; + if (bucket == null) { + newNode.next = bucket; + buckets[index] = newNode; + size++; + } else if (Objects.equals(bucket.key, newNode.key)) { + bucket.value = newNode.value; + } else { + while (bucket.next != null) { + if (Objects.equals(bucket.key, newNode.key)) { + bucket.value = newNode.value; + return; + } + bucket = bucket.next; + } + bucket.next = newNode; + size++; + } + } + + private static class Node { + private final K key; + private V value; + private Node next; + + Node(K key, V value) { + this.key = key; + this.value = value; + } } }