Understanding the Different Data-structures

Udaykishore Resu
3 min readOct 27, 2024

--

Arrays are fixed-size, contiguous memory blocks that store elements of the same data type.
Internal Structure: Elements are stored in adjacent memory locations, allowing for constant-time access using indices.

Usage Scenario: When you need a fixed-size collection with fast access by index.

Real-time Use Case: Storing a list of fixed-size data, like months of the year or days of the week.

int[] numbers = new int[5];
numbers[0] = 1;

ArrayList is a resizable array implementation of the List interface.
Internal Structure: Backed by a dynamic array that grows as needed.

Usage Scenario: When you need frequent read operations and infrequent insert/delete operations.

Real-time Use Case: Implementing a shopping cart in an e-commerce application. Ex: Amazon Cart

ArrayList<String> shoppingCart = new ArrayList<>();
shoppingCart.add("Laptop");

LinkedList is a doubly linked list implementation of the List interface.

Internal Structure: Each element (node) contains data and references to the previous and next nodes.

Usage Scenario: When you need frequent insert/delete operations, especially at the beginning or end of the list.

Real-time Use Case: Implementing an undo/redo functionality in a text editor. Ex: Playlist

LinkedList<String> actions = new LinkedList<>();
actions.addFirst("Type 'Hello'");

Stack is a Last-In-First-Out (LIFO) data structure.

Internal Structure: Typically implemented using an array or linked list.

Usage Scenario: When you need to process elements in reverse order of their addition.

Real-time Use Case: Implementing the back button functionality in a web browser.

Stack<String> browserHistory = new Stack<>();
browserHistory.push("https://www.example.com");

PriorityQueue is a queue where elements are ordered based on their natural order or a custom comparator.

Internal Structure: Typically implemented using a heap data structure.

Usage Scenario: When you need to process elements based on their priority.

Real-time Use Case: Implementing a task scheduler where tasks have different priorities. Ex: Emergency Patient

PriorityQueue<Integer> taskPriorities = new PriorityQueue<>();
taskPriorities.offer(5);

Vector is a thread-safe, dynamic array implementation like ArrayList.

Internal Structure: Backed by a resizable array, with synchronized methods for thread safety.

Usage Scenario: When you need a thread-safe, dynamically growing array.

Real-time Use Case: Implementing a shared resource list in a multi-threaded application.

Vector<String> sharedResources = new Vector<> ();
sharedResources.add("Database Connection");

Deque (double-ended queue) allows insertion and removal at both ends.

Internal Structure: Can be implemented using a doubly linked list or a circular array.

Usage Scenario: When you need to add or remove elements from both ends efficiently.

Real-time Use Case: Implementing a palindrome checker. Ex: Browser History

Deque<Character> palindrome = new ArrayDeque<>();
palindrome.addFirst('r');
palindrome.addLast('a');

HashSet is an unordered collection that does not allow duplicates.

Internal Structure: Backed by a hash table (HashMap).

Usage Scenario: When you need to store unique elements and don’t care about order.

Real-time Use Case: Implementing a unique visitor counter for a website.

Ex: Subscribers

HashSet<String> uniqueVisitors = new HashSet<>();
uniqueVisitors.add("user123");

LinkedHashSet is an ordered version of HashSet that maintains insertion order.

Internal Structure: Combines a hash table with a linked list to maintain order.

Usage Scenario: When you need to store unique elements and maintain insertion order.

Real-time Use Case: Implementing a cache with a “least recently used” eviction policy. Ex: Tracking user actions on a website

LinkedHashSet<String> cache = new LinkedHashSet<>();
cache.add("recentItem");

TreeSet is a sorted set implementation based on a tree structure.

Internal Structure: Typically implemented using a self-balancing binary search tree (Red-Black tree).

Usage Scenario: When you need to store unique elements in sorted order.

Real-time Use Case: Implementing a leaderboard in a game.

TreeSet<Integer> leaderboard = new TreeSet<>();
leaderboard.add(1000);

HashMap

Internal Structure:
HashMap uses an array of linked lists (or balanced trees in Java 8+) to store key-value pairs.

Usage Scenario:
Use HashMap when you need fast insertion, deletion, and lookup operations, and don’t require keys to be sorted.

Real-time Use Case:
Implementing a cache system where quick access to data based on unique identifiers is crucial, such as a user session store in a web application.

HashMap<KeyType, ValueType> mapName = new HashMap<>();
mapName.put(key, value);

TreeMap

Internal Structure: TreeMap is implemented as a Red-Black tree, a self-balancing binary search tree.

Usage Scenario: Use TreeMap when you need to maintain keys in a sorted order or require operations that depend on ordering, like finding the closest matches or ranges of keys.

Real-time Use Case: Implementing a leaderboard system in a game where scores (keys) need to be kept in sorted order, allowing for efficient retrieval of top scores or score ranges.

TreeMap<Integer, String> leaderboard = new TreeMap<>(Collections.reverseOrder()); 
leaderboard.put(100, "nani");

--

--

Udaykishore Resu
Udaykishore Resu

Written by Udaykishore Resu

Senior Software Engineer with 11+ years in cloud tech, API design, and microservices. Expertise in Golang, Java, Scala. AWS certified. Based in Atlanta, USA.

No responses yet