2025-11-22 18:18:23 -05:00
2025-11-22 18:18:23 -05:00
2025-11-22 18:18:23 -05:00
2025-11-22 18:18:23 -05:00
2025-11-22 18:18:23 -05:00
2025-11-22 18:18:23 -05:00
2025-11-22 18:18:23 -05:00
2025-11-22 18:18:23 -05:00
2025-11-22 18:18:23 -05:00
2025-11-22 18:18:23 -05:00
2025-11-22 18:18:23 -05:00

@techniker-me/hash-map

A robust, production-ready HashMap implementation in TypeScript following OOP SOLID principles and best practices.

Features

Generic Type Support - Fully typed keys and values with TypeScript generics
🔧 Custom Hash Functions - Inject your own hashing strategies
Automatic Resizing - Dynamic capacity adjustment based on load factor
🔗 Collision Resolution - Separate chaining for handling hash collisions
🔄 Full Iterator Support - Compatible with for...of, keys(), values(), entries(), and forEach()
📦 Zero Dependencies - Lightweight and self-contained
🎯 SOLID Principles - Clean, maintainable, and extensible architecture
100% Test Coverage - 66 comprehensive tests with 100% line coverage using Bun test runner

Installation

bun add @techniker-me/hash-map

Quick Start

import { HashMap } from "@techniker-me/hash-map";

// Create a new HashMap
const map = new HashMap<string, number>();

// Add entries
map.set("Alice", 95);
map.set("Bob", 87);
map.set("Charlie", 92);

// Retrieve values
console.log(map.get("Alice")); // 95

// Check existence
console.log(map.has("Bob")); // true

// Delete entries
map.delete("Bob");

// Iterate over entries
for (const [name, score] of map) {
  console.log(`${name}: ${score}`);
}

// Get size
console.log(map.size); // 2

API Reference

Constructor

new HashMap<K, V>(
  initialCapacity?: number,      // Default: 16
  loadFactorThreshold?: number,  // Default: 0.75
  hashFunction?: IHashFunction<K> // Default: DefaultHashFunction
)

Methods

Method Description Time Complexity
set(key: K, value: V): void Insert or update a key-value pair O(1) average
get(key: K): V | undefined Retrieve value by key O(1) average
has(key: K): boolean Check if key exists O(1) average
delete(key: K): boolean Remove entry by key O(1) average
clear(): void Remove all entries O(n)
keys(): IterableIterator<K> Iterator over keys O(n)
values(): IterableIterator<V> Iterator over values O(n)
entries(): IterableIterator<[K, V]> Iterator over entries O(n)
forEach(callback): void Execute callback for each entry O(n)

Properties

Property Description
size Number of key-value pairs
capacity Current number of buckets
loadFactor Current load factor (size / capacity)

Advanced Usage

Custom Hash Functions

Implement the IHashFunction<K> interface to create custom hashing strategies:

import { HashMap, IHashFunction } from "@techniker-me/hash-map";

class CaseInsensitiveHashFunction implements IHashFunction<string> {
  hash(key: string, capacity: number): number {
    const lowerKey = key.toLowerCase();
    let hash = 0;
    for (let i = 0; i < lowerKey.length; i++) {
      hash = (hash << 5) - hash + lowerKey.charCodeAt(i);
      hash = hash & hash;
    }
    return Math.abs(hash) % capacity;
  }
}

const map = new HashMap<string, number>(
  16,
  0.75,
  new CaseInsensitiveHashFunction()
);

map.set("Hello", 1);
console.log(map.get("HELLO")); // 1 (case-insensitive)

Numeric Keys

Use the built-in NumericHashFunction for better distribution with numeric keys:

import { HashMap, NumericHashFunction } from "@techniker-me/hash-map";

const map = new HashMap<number, string>(
  16,
  0.75,
  new NumericHashFunction()
);

map.set(12345, "value1");
map.set(67890, "value2");

Working with Complex Types

interface User {
  id: number;
  name: string;
  email: string;
}

const users = new HashMap<number, User>();

users.set(1, { id: 1, name: "Alice", email: "alice@example.com" });
users.set(2, { id: 2, name: "Bob", email: "bob@example.com" });

const user = users.get(1);
console.log(user?.name); // "Alice"

SOLID Principles

This implementation adheres to all five SOLID principles:

1. Single Responsibility Principle (SRP)

  • HashMap - Manages hash map operations
  • HashNode - Stores key-value pairs
  • DefaultHashFunction - Handles hashing logic
  • Each class has one clear purpose

2. Open/Closed Principle (OCP)

  • Extensible through custom hash functions
  • Core implementation is closed for modification

3. Liskov Substitution Principle (LSP)

  • All implementations correctly implement their interfaces
  • Subtypes can replace their base types without breaking functionality

4. Interface Segregation Principle (ISP)

  • IHashMap - Focused map operations
  • IHashFunction - Minimal hashing interface
  • Clients depend only on interfaces they use

5. Dependency Inversion Principle (DIP)

  • Depends on IHashFunction abstraction, not concrete implementations
  • High-level modules don't depend on low-level modules

Architecture

src/
├── core/
│   └── HashMap.ts              # Main HashMap implementation
├── interfaces/
│   ├── IHashMap.ts             # HashMap interface
│   └── IHashFunction.ts        # Hash function interface
├── models/
│   └── HashNode.ts             # Node for collision chains
├── hash-functions/
│   ├── DefaultHashFunction.ts  # Default hashing strategy
│   └── NumericHashFunction.ts  # Numeric key optimization
├── examples/
│   ├── basic-usage.ts          # Basic usage examples
│   └── custom-hash-function.ts # Advanced examples
└── index.ts                    # Public API exports

Performance

  • Average Case: O(1) for all basic operations (get, set, has, delete)
  • Worst Case: O(n) when all keys collide (very rare with good hash functions)
  • Space Complexity: O(n) where n is the number of entries
  • Automatic Resizing: Triggers when load factor exceeds threshold (default 0.75)

Examples

Running Examples

# Basic usage examples
bun run src/examples/basic-usage.ts

# Custom hash function examples
bun run src/examples/custom-hash-function.ts

Testing

# Run all tests
bun test

# Run tests in watch mode
bun test --watch

# Run tests with coverage report
bun test --coverage

Test Coverage: 100%

  • 66 comprehensive tests
  • 1,168 assertions
  • All edge cases covered
  • See TESTING.md for detailed test documentation

Development

# Install dependencies
bun install

# Run tests
bun test

# Run examples
bun run src/examples/basic-usage.ts

License

MIT

Author

Techniker.me


Built with ❤️ using Bun

Description
No description provided
Readme 125 KiB
Languages
TypeScript 94.2%
Shell 5.8%