HashSet Data Structure Explained

Learn HashSet Data Structure Explained with practical examples, explanations, best practices, and real-world coding techniques.

What Is a HashSet?

A HashSet is a hash-based data structure designed to store a collection of unique elements. Unlike a HashMap, which stores data as key-value pairs, a HashSet stores values where each value can appear only once.

HashSet is useful when the main requirement is to quickly determine whether an element exists and to prevent duplicate values.

const languages = new Set();

languages.add("JavaScript");
languages.add("Python");
languages.add("JavaScript");

console.log(languages);

// Set(2) { "JavaScript", "Python" }

The second "JavaScript" value is ignored because a Set does not store duplicate values.

HashSet vs HashMap

HashSet and HashMap both use hashing concepts, but they solve different problems.

Feature HashSet HashMap
Stores Values Key-value pairs
Duplicates Not allowed Keys are unique
Main purpose Unique values and membership Key-based lookup
Typical lookup Is this value present? What value belongs to this key?

How a HashSet Works

A HashSet typically uses a hash function to transform each value into a hash value. The hash is then used to determine where the value should be stored.

Value → Hash Function → Hash Value → Bucket → Stored Value

When a value is added, the implementation calculates its hash and checks the corresponding location. If an equivalent value is already present, another copy is not inserted.

The exact implementation differs between programming languages, but the underlying idea is to use hashing for efficient membership operations.

Creating a HashSet in JavaScript

JavaScript provides the built-in Set object for HashSet-style behavior. A Set stores unique values and provides operations for insertion, membership checking, deletion, and iteration.

const users = new Set();

users.add("John");
users.add("Maya");
users.add("Alex");

console.log(users);

You can also create a Set from an existing iterable such as an array.

const numbers = new Set([10, 20, 30, 20, 10]);

console.log(numbers);
// Set(3) { 10, 20, 30 }

Adding Elements to a HashSet

Use add() to insert an element. Adding a value that already exists does not create a duplicate.

const skills = new Set();

skills.add("HTML");
skills.add("CSS");
skills.add("JavaScript");
skills.add("JavaScript");

console.log(skills);
// Set(3) { "HTML", "CSS", "JavaScript" }

The JavaScript add() method returns the Set itself, which also allows chained calls.

const skills = new Set();

skills
  .add("HTML")
  .add("CSS")
  .add("JavaScript");

Checking Whether an Element Exists

The has() operation checks whether a value is present in the HashSet.

const roles = new Set([
  "Developer",
  "Designer",
  "Tester"
]);

console.log(roles.has("Developer"));
// true

console.log(roles.has("Manager"));
// false

Membership checking is one of the main reasons to use a HashSet instead of repeatedly scanning an array.

Removing Elements

Use delete() to remove a value. The method returns true when an element was removed and false when the value was not present.

const languages = new Set([
  "JavaScript",
  "Python",
  "Java"
]);

console.log(languages.delete("Python"));
// true

console.log(languages.delete("C#"));
// false

console.log(languages);

Getting the Size of a HashSet

The size property tells you how many unique elements are currently stored.

const numbers = new Set([10, 20, 20, 30]);

console.log(numbers.size);
// 3

Iterating Through a HashSet

A HashSet can be traversed when you need to process each unique value.

const technologies = new Set([
  "HTML",
  "CSS",
  "JavaScript"
]);

for (const technology of technologies) {
  console.log(technology);
}

JavaScript Sets also provide values() and keys(). For a Set, both represent the stored values.

for (const value of technologies.values()) {
  console.log(value);
}

Removing All Elements

Use clear() when the entire HashSet should be emptied.

const users = new Set([
  "John",
  "Maya",
  "Alex"
]);

users.clear();

console.log(users.size);
// 0

Using HashSet to Remove Duplicates

A common HashSet use case is removing duplicate values from a collection. In JavaScript, an array can be converted to a Set and then converted back into an array.

const numbers = [10, 20, 10, 30, 20, 40];

const uniqueNumbers = [...new Set(numbers)];

console.log(uniqueNumbers);
// [10, 20, 30, 40]

This is particularly useful when an application receives repeated IDs, tags, categories, or other values that should be unique.

HashSet and Set Operations

A mathematical set can be combined with another set using operations such as union, intersection, and difference. JavaScript's Set object does not require these operations to be performed using a special HashSet class; they can be implemented with iteration and membership checks.

Union

The union contains values that appear in either set.

const frontend = new Set(["HTML", "CSS", "JavaScript"]);
const backend = new Set(["C#", "JavaScript", "SQL"]);

const union = new Set([...frontend, ...backend]);

console.log(union);
// HTML, CSS, JavaScript, C#, SQL

Intersection

The intersection contains values that exist in both sets.

const frontend = new Set(["HTML", "CSS", "JavaScript"]);
const backend = new Set(["C#", "JavaScript", "SQL"]);

const common = new Set(
  [...frontend].filter(skill => backend.has(skill))
);

console.log(common);
// JavaScript

Difference

The difference contains values that exist in the first set but not in the second.

const frontend = new Set(["HTML", "CSS", "JavaScript"]);
const backend = new Set(["C#", "JavaScript", "SQL"]);

const onlyFrontend = new Set(
  [...frontend].filter(skill => !backend.has(skill))
);

console.log(onlyFrontend);
// HTML, CSS

HashSet and Object Values

A HashSet can also contain objects. However, object uniqueness is based on object identity rather than automatically comparing whether two objects contain the same data.

const users = new Set();

const user1 = { id: 1, name: "John" };
const user2 = { id: 1, name: "John" };

users.add(user1);
users.add(user2);

console.log(users.size);
// 2

Although both objects contain the same properties and values, they are separate object references. If uniqueness should be based on an ID, store the IDs in a Set instead.

const userIds = new Set();

userIds.add(1);
userIds.add(1);

console.log(userIds.size);
// 1

HashSet Time Complexity

HashSet implementations are generally designed to provide constant-time average performance for basic membership and modification operations.

Operation Average Worst Case
Add O(1) O(n)
Search / Contains O(1) O(n)
Delete O(1) O(n)

Actual performance depends on factors such as the quality of hashing, collision handling, load factor, resizing, and the specific implementation.

HashSet Space Complexity

A HashSet requires storage for the elements and its internal hash-table structures. If n unique elements are stored, the typical space complexity is O(n).

HashSet vs Array

Both arrays and HashSets can store collections of values, but their strengths are different.

Feature Array HashSet
Duplicates Allowed Not stored
Membership search O(n) with includes() O(1) average
Index access Supported Not index-based
Primary purpose Ordered collection Unique values and membership

HashSet vs HashMap

Choose a HashSet when you only need to know whether values exist. Choose a HashMap when each key needs to be associated with additional information.

// HashSet
const visited = new Set();

visited.add("page-home");
visited.add("page-profile");


// HashMap
const userRoles = new Map();

userRoles.set("u101", "Developer");
userRoles.set("u102", "Designer");

HashSet in Duplicate Detection

A Set can detect duplicate values while processing an array. Keep track of values that have already appeared and check membership before adding the next value.

function hasDuplicate(numbers) {
  const seen = new Set();

  for (const number of numbers) {
    if (seen.has(number)) {
      return true;
    }

    seen.add(number);
  }

  return false;
}

console.log(hasDuplicate([10, 20, 30, 20]));
// true

console.log(hasDuplicate([10, 20, 30, 40]));
// false

The algorithm avoids comparing every pair of elements. With average O(1) Set membership checks, the overall approach takes O(n) average time and O(n) additional space.

HashSet in Graph Algorithms

HashSets are frequently used with graph traversal algorithms such as BFS and DFS to track vertices that have already been visited.

const graph = {
  A: ["B", "C"],
  B: ["A", "D"],
  C: ["A"],
  D: ["B"]
};

const visited = new Set();

function dfs(node) {
  if (visited.has(node)) {
    return;
  }

  visited.add(node);

  for (const neighbor of graph[node] ?? []) {
    dfs(neighbor);
  }
}

dfs("A");

console.log(visited);
// Set { "A", "B", "D", "C" }

Without a visited Set, a graph containing cycles could cause the traversal to repeatedly process the same vertices.

When Should You Use a HashSet?

A HashSet is a natural choice when uniqueness or fast membership checking is more important than positional access.

  • Removing duplicate values.
  • Checking whether an item has already been processed.
  • Tracking visited graph nodes.
  • Maintaining a collection of unique IDs.
  • Detecting duplicate records.
  • Checking membership efficiently.
  • Maintaining unique tags or categories.
  • Comparing collections using set operations.

Common HashSet Mistakes

Expecting Index-Based Access

A HashSet is not an array. It does not provide direct access using positions such as set[0]. If your application needs frequent index-based access, an array may be a better fit.

Assuming Duplicate Objects Are Automatically Removed

Objects can be considered different when they are different references. If uniqueness is based on an ID or another property, explicitly store that identifying value or implement the appropriate equality strategy in the language being used.

Assuming HashSet Operations Are Always O(1)

Hash-based structures generally provide O(1) average performance, not an unconditional O(1) guarantee for every implementation and workload. Poor hashing and collisions can affect performance.

Using a HashSet When Values Need to Be Sorted

A basic HashSet is focused on uniqueness and membership. If maintaining sorted order is a core requirement, a tree-based set or sorting step may be more appropriate.

HashSet in Coding Interviews

HashSet is a common interview tool because many problems can be simplified by tracking which values have already appeared.

  • Find duplicate elements.
  • Find the first repeated value.
  • Find the first unique value with additional counting logic.
  • Track visited nodes in graphs.
  • Detect cycles or repeated states in certain algorithms.
  • Determine whether two collections share common values.
  • Remove duplicates from input data.

Practical Example: Unique Developer Skills

Imagine an application collecting skills from multiple projects. The same skill may appear repeatedly, but the final profile should contain each skill only once.

const projectSkills = [
  "JavaScript",
  "TypeScript",
  "Angular",
  "JavaScript",
  "C#",
  "Angular",
  "SQL"
];

const uniqueSkills = new Set(projectSkills);

console.log([...uniqueSkills]);
// [
//   "JavaScript",
//   "TypeScript",
//   "Angular",
//   "C#",
//   "SQL"
// ]

console.log(uniqueSkills.has("Angular"));
// true

The Set provides both uniqueness and efficient membership checking without requiring separate duplicate-removal logic.

HashSet: Key Characteristics

Characteristic Description
Storage Unique values
Lookup Hash-based membership checking
Duplicates Not stored
Average add O(1)
Average search O(1)
Average delete O(1)
Typical space O(n)

Key Takeaways

  • A HashSet stores unique values rather than key-value pairs.
  • Hashing enables efficient average-case membership operations.
  • Adding an existing value does not create a duplicate.
  • JavaScript's Set provides HashSet-style functionality.
  • HashSets are useful for duplicate detection and removal.
  • They are commonly used to track visited elements in graph algorithms.
  • Average insertion, search, and deletion are typically O(1).
  • A HashSet is not designed for index-based access.
  • If sorted order or positional access is required, another data structure may be more suitable.

Code Examples

const skills = new Set();

skills.add("HTML");
skills.add("CSS");
skills.add("JavaScript");
skills.add("JavaScript");

console.log(skills);

console.log(skills.has("CSS"));

skills.delete("CSS");

console.log(skills.size);
    
const numbers = [10, 20, 10, 30, 20, 40];

const uniqueNumbers = [...new Set(numbers)];

console.log(uniqueNumbers);
// [10, 20, 30, 40]
    
function hasDuplicate(numbers) {
  const seen = new Set();

  for (const number of numbers) {
    if (seen.has(number)) {
      return true;
    }

    seen.add(number);
  }

  return false;
}

console.log(hasDuplicate([1, 2, 3, 2]));
// true

console.log(hasDuplicate([1, 2, 3, 4]));
// false
    

Pro Tip

If a problem asks whether an element has already appeared, consider a HashSet before using nested loops. A Set can often turn repeated membership checks into an O(n) average-time solution.

🎨 IgKnight Docs

Master HTML, CSS, JS, Python, .NET and more with easy-to-follow lessons and practical code examples.

© 2025 IgKnight Learning Platform. All rights reserved.