Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md → src/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ Be attentive to basic requirements for the implementation of the map (initial ca

P.S.: you can implement other methods of the Map interface.

[Try to avoid these common mistakes while solving task](./checklist.md)
[Try to avoid these common mistakes while solving task](../checklist.md)
95 changes: 95 additions & 0 deletions src/test/java/core/basesyntax/MyHashMap.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package core.basesyntax;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid redundant empty lines like this one. There are several of them in the file (e.g., lines 4, 8, 12, 17, etc.), which reduces readability.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are several redundant empty lines throughout the file (e.g., here, and on lines 4, 9, 13, etc.). Please remove them to improve code readability and adhere to the style guide.

import java.util.Objects;
public class MyHashMap<K, V> implements MyMap<K, V> {
private static final int DEFAULT_CAPACITY = 16;
private static final float DEFAULT_LOAD_FACTOR = 0.75f;
private static final int RESIZE_MULTIPLIER = 2;
private Node<K, V>[] table;
private int size;
private int threshold;

public MyHashMap() {
table = new Node[DEFAULT_CAPACITY];
threshold = (int) (DEFAULT_CAPACITY * DEFAULT_LOAD_FACTOR);
}

@Override
public void put(K key, V value) {
if (size >= threshold) {
resize();
}
int index = getIndex(key, table.length);
Node<K, V> current = table[index];
if (current == null) {
table[index] = new Node<>(key, value, null);
size++;
return;
}
Node<K, V> prev = null;
while (current != null) {
if (Objects.equals(current.key, key)) {
current.value = value;
return;
}
prev = current;
current = current.next;
}
prev.next = new Node<>(key, value, null);
size++;
Comment on lines +23 to +39

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic for adding a new element to a bucket can be simplified. Currently, you are traversing the linked list to add a new node at the end. A more common and slightly more efficient approach is to add new nodes to the beginning of the list. This avoids the need to iterate to the end and simplifies the code by removing the prev variable and the special check for an empty bucket. You could refactor this block to first iterate through the list to check if the key already exists, and if not, add the new node at the head of the bucket.

}

@Override
public V getValue(K key) {
int index = getIndex(key, table.length);
Node<K, V> current = table[index];
while (current != null) {
if (Objects.equals(current.key, key)) {
return current.value;
}
current = current.next;
}
return null;
}

@Override
public int getSize() {
return size;
}

private void resize() {
Node<K, V>[] oldTable = table;
int newCapacity = oldTable.length * RESIZE_MULTIPLIER;
table = new Node[newCapacity];
threshold = (int) (newCapacity * DEFAULT_LOAD_FACTOR);
size = 0;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the resize method, resetting size to 0 and then incrementing it for each element is unnecessary. The number of elements in the map does not change during a resize operation. You can simplify the method by removing this line and the size++ line (line 77) within the loop.

for (Node<K, V> headNode : oldTable) {
while (headNode != null) {
Node<K, V> nextNode = headNode.next;
int index = getIndex(headNode.key, newCapacity);
headNode.next = table[index];
table[index] = headNode;
size++;
headNode = nextNode;
}
}
}

private int getIndex(K key, int length) {
if (key == null) {
return 0;
}
return (key.hashCode() & 0x7fffffff) % length;
}

private static class Node<K, V> {
private final K key;
private V value;
private Node<K, V> next;
Node(K key, V value, Node<K, V> next) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Node constructor has default (package-private) access. Since Node is a private static inner class and its constructor is only invoked from within the enclosing MyHashMap class, you can declare the constructor as private to strengthen encapsulation.

this.key = key;
this.value = value;
this.next = next;
}
}
}
7 changes: 7 additions & 0 deletions src/test/java/core/basesyntax/MyMap.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package core.basesyntax;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid a redundant empty line after the package declaration.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are several redundant empty lines in the interface definition (e.g., here, and on lines 5 and 7). Please remove them to make the code more compact and clean, following the coding style guidelines.

public interface MyMap<K, V> {
void put(K key, V value);
V getValue(K key);
int getSize();
}