Skip to content

Commit d371dae

Browse files
authored
Merge pull request #3 from KaririCode-Framework/develop
Add HashMap Implementation and Comprehensive Unit Tests
2 parents 07351e8 + 4869c87 commit d371dae

File tree

3 files changed

+181
-3
lines changed

3 files changed

+181
-3
lines changed

src/Collection/LinkedList.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,13 +138,13 @@ public function set(int $index, mixed $element): void
138138
}
139139

140140
/**
141-
* Clone method to ensure deep copy of nodes
142-
*/
141+
* Clone method to ensure deep copy of nodes.
142+
*/
143143
public function __clone()
144144
{
145145
$newList = new LinkedList();
146146
$current = $this->head;
147-
while ($current !== null) {
147+
while (null !== $current) {
148148
$newList->add($current->data);
149149
$current = $current->next;
150150
}

src/Map/HashMap.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace KaririCode\DataStructure\Map;
6+
7+
use KaririCode\Contract\DataStructure\Map;
8+
9+
/**
10+
* HashMap implementation.
11+
*
12+
* This class implements a hash map using PHP's built-in array as the underlying storage.
13+
* It provides O(1) average time complexity for put, get, and remove operations.
14+
*
15+
* @category Maps
16+
*
17+
* @author Walmir Silva <walmir.silva@kariricode.org>
18+
* @license MIT
19+
*
20+
* @see https://kariricode.org/
21+
*/
22+
class HashMap implements Map
23+
{
24+
private array $map = [];
25+
26+
public function put(mixed $key, mixed $value): void
27+
{
28+
$this->map[$key] = $value;
29+
}
30+
31+
public function get(mixed $key): mixed
32+
{
33+
return $this->map[$key] ?? null;
34+
}
35+
36+
public function remove(mixed $key): bool
37+
{
38+
if (array_key_exists($key, $this->map)) {
39+
unset($this->map[$key]);
40+
41+
return true;
42+
}
43+
44+
return false;
45+
}
46+
47+
public function containsKey(mixed $key): bool
48+
{
49+
return array_key_exists($key, $this->map);
50+
}
51+
52+
public function size(): int
53+
{
54+
return count($this->map);
55+
}
56+
57+
public function clear(): void
58+
{
59+
$this->map = [];
60+
}
61+
62+
public function keys(): array
63+
{
64+
return array_keys($this->map);
65+
}
66+
67+
public function values(): array
68+
{
69+
return array_values($this->map);
70+
}
71+
}

tests/Map/HashMapTest.php

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace KaririCode\DataStructure\Tests\Map;
6+
7+
use KaririCode\DataStructure\Map\HashMap;
8+
use PHPUnit\Framework\TestCase;
9+
10+
final class HashMapTest extends TestCase
11+
{
12+
// Test adding a key-value pair to the map
13+
public function testPutAddsKeyValuePairToMap(): void
14+
{
15+
$map = new HashMap();
16+
$map->put('key1', 'value1');
17+
$this->assertSame('value1', $map->get('key1'));
18+
}
19+
20+
// Test retrieving a value by key
21+
public function testGetReturnsValueForKey(): void
22+
{
23+
$map = new HashMap();
24+
$map->put('key1', 'value1');
25+
$this->assertSame('value1', $map->get('key1'));
26+
$this->assertNull($map->get('key2'));
27+
}
28+
29+
// Test removing a key-value pair by key
30+
public function testRemoveDeletesKeyValuePairFromMap(): void
31+
{
32+
$map = new HashMap();
33+
$map->put('key1', 'value1');
34+
$this->assertTrue($map->remove('key1'));
35+
$this->assertFalse($map->remove('key2'));
36+
$this->assertNull($map->get('key1'));
37+
}
38+
39+
// Test checking if the map contains a specific key
40+
public function testContainsKeyReturnsTrueIfKeyExists(): void
41+
{
42+
$map = new HashMap();
43+
$map->put('key1', 'value1');
44+
$this->assertTrue($map->containsKey('key1'));
45+
$this->assertFalse($map->containsKey('key2'));
46+
}
47+
48+
// Test clearing all key-value pairs from the map
49+
public function testClearRemovesAllKeyValuePairsFromMap(): void
50+
{
51+
$map = new HashMap();
52+
$map->put('key1', 'value1');
53+
$map->put('key2', 'value2');
54+
$map->clear();
55+
$this->assertSame(0, $map->size());
56+
$this->assertNull($map->get('key1'));
57+
$this->assertNull($map->get('key2'));
58+
}
59+
60+
// Test getting all keys from the map
61+
public function testKeysReturnsAllKeysInMap(): void
62+
{
63+
$map = new HashMap();
64+
$map->put('key1', 'value1');
65+
$map->put('key2', 'value2');
66+
$this->assertSame(['key1', 'key2'], $map->keys());
67+
}
68+
69+
// Test getting all values from the map
70+
public function testValuesReturnsAllValuesInMap(): void
71+
{
72+
$map = new HashMap();
73+
$map->put('key1', 'value1');
74+
$map->put('key2', 'value2');
75+
$this->assertSame(['value1', 'value2'], $map->values());
76+
}
77+
78+
// Test getting the size of the map
79+
public function testSizeReturnsNumberOfKeyValuePairsInMap(): void
80+
{
81+
$map = new HashMap();
82+
$this->assertSame(0, $map->size());
83+
$map->put('key1', 'value1');
84+
$map->put('key2', 'value2');
85+
$this->assertSame(2, $map->size());
86+
}
87+
88+
// Test handling null values in the map
89+
public function testHandlingNullValuesCorrectly(): void
90+
{
91+
$map = new HashMap();
92+
$map->put('key1', null);
93+
$this->assertTrue($map->containsKey('key1'));
94+
$this->assertNull($map->get('key1'));
95+
$this->assertTrue($map->remove('key1'));
96+
$this->assertFalse($map->containsKey('key1'));
97+
}
98+
99+
// Test replacing a value for an existing key
100+
public function testPutReplacesValueForExistingKey(): void
101+
{
102+
$map = new HashMap();
103+
$map->put('key1', 'value1');
104+
$map->put('key1', 'value2');
105+
$this->assertSame('value2', $map->get('key1'));
106+
}
107+
}

0 commit comments

Comments
 (0)