This beginner-friendly guide covers Data Structures and Algorithms (DSA) in Java, including built-in structures like arrays, strings, ArrayList, HashMap, HashSet, and user-defined structures such as linked lists, stacks, queues, trees, heaps, and graphs. It also explains how to analyze algorithm efficiency.
It is recommended to read about Analysis of Algorithms before beginning this tutorial.
1. Array
In Java, there are mainly two types of arrays.
- Array : Fixed-size collection of similar data types stored contiguously, ideal when element count is known.
- ArrayList :  Dynamic and grow as needed. It is from the Java Collections Framework, suitable when element count varies. 
Javaimport java.util.*;
class Geeks{
    public static void main(String[] args) {
        
        // Array example
        int[] arr = {10, 20, 30, 40, 50};
        System.out.println(Arrays.toString(arr));
        // ArrayList example
        ArrayList<Integer> list = new ArrayList<>();
        list.add(10);
        list.add(20);
        list.add(30);
        System.out.println(list);
    }
}
Output[10, 20, 30, 40, 50]
[10, 20, 30]
 Related Posts:
Recommended DSA Problems:
2. Searching Algorithms
Searching algorithms help locate an element in data structures like arrays or lists. Java provides both linear search and binary search (via Arrays.binarySearch).
            Java
    import java.util.*;
class Geeks {
    public static void main(String[] args) {
        
        List<Integer> list = Arrays.asList(2, 4, 6, 8, 10);
        int key = 6;
        
        // Linear search
        System.out.println("Linear Search: " + list.contains(key));
        // Binary search using Collections.binarySearch 
        // (list must be sorted)
        int index = Collections.binarySearch(list, key);
        if (index >= 0) {
            System.out.println("Element found at index " + index);
        } else {
            System.out.println("Element not found");
        }
    }
}
OutputLinear Search: true
Element found at index 2
 Related Posts:
Recommended DSA Problems:
4. Sorting Algorithms
Sorting arranges elements in ascending or descending order. Java provides built-in sorting using Arrays.sort() but you can also implement algorithms like Bubble Sort, QuickSort, and MergeSort.
            Java
    import java.util.*;
class Geeks {
    public static void main(String[] args) {
        
        // Array example
        int[] nums = {5, 3, 8, 1};
        Arrays.sort(nums);
        System.out.println("Sorted array: " + Arrays.toString(nums));
        // List example
        List<Integer> list = new ArrayList<>(Arrays.asList(5, 3, 8, 1));
        Collections.sort(list);
        System.out.println("Sorted list: " + list);
    }
}
OutputSorted array: [1, 3, 5, 8]
Sorted list: [1, 3, 5, 8]
 Related Posts:
Recommended DSA Problems:
5. String
In Java, there are mainly three types of strings:
- String: An immutable sequence of characters used to store text in Java.
- StringBuilder: A mutable sequence of characters used for efficient text modification in single-threaded scenarios.
- StringBuffer: A mutable and thread-safe sequence of characters used for text modification in multi-threaded scenarios.
Javaclass Geeks {
    public static void main(String[] args) {
        
        // Immutable String
        String s = "Hello Geeks";
        System.out.println(s);
        
        // Mutable StringBuilder
        StringBuilder sb = new StringBuilder("Hello");
        sb.append(" Geeks");
        System.out.println(sb.toString());
    }
}
OutputHello Geeks
Hello Geeks
 Related Posts:
Recommended DSA Problems:
6. Set
A Set in Java is a collection that does not allow duplicate elements. Implementations include HashSet, LinkedHashSet, and TreeSet.
- HashSet :  Implements hashing where we can store keys without any specific order, but fast search, insert and delete operations.
- LinkedHashSet : Similar to HashSet with and additional advantage that insertion order is maintained.
- TreeSet : Implements Self Balancing Binary Search Tree. It is useful to maintain a sorted set of items with moderate time for insertion, search and deletion.
Javaimport java.util.*;
class Geeks{
    public static void main(String[] args) {
        
        Set<Object> set = new HashSet<>();
        set.add(10);
        set.add(20);
        set.add(20);
        set.add("GfG");
        set.add(true);
        System.out.println(set);
    }
}
Output[20, GfG, 10, true]
 Related Posts:
Recommended DSA Problems:
7. Dictionary (HashMap)
In Java, HashMap is used to store data as key-value pairs. Keys must be unique, while values can be duplicated.
            Java
    import java.util.*;
class Geeks{
    public static void main(String[] args) {
        
        Map<Object, Object> map = new HashMap<>();
        map.put(10, "hello");
        map.put(20, "geek");
        map.put("hello", "world");
        map.put(2.0, 55);
        System.out.println(map);
    }
}
Output{2.0=55, 20=geek, 10=hello, hello=world}
 Related Posts:
Recommended DSA Problems:
8. Recursion
Recursion is a technique where a method calls itself to solve smaller subproblems.
            Java
    class Geeks{
    
    static int fact(int n) {
        
        if (n == 0) return 1;
        return n * fact(n - 1);
    }
    public static void main(String[] args)
    {
        System.out.println(fact(5));
    }
}
Related Posts:
Recommended DSA Problems:
9. Queue
A queue follows the FIFO (First In First Out) principle. Java provides Queue interface and classes like LinkedList or PriorityQueue.
            Java
    import java.util.*;
class Geeks{
    public static void main(String[] args){
        
        Queue<String> queue = new LinkedList<>();
        queue.add("g");
        queue.add("f");
        queue.add("g");
        System.out.println("Initial queue: " + queue);
        System.out.println("Dequeued: " + queue.remove());
        System.out.println("Queue after dequeue: " + queue);
    }
}
OutputInitial queue: [g, f, g]
Dequeued: g
Queue after dequeue: [f, g]
 Related Posts:
Recommended DSA Problems:
10. Stack
A stack follows the LIFO (Last In First Out) principle. In Java, you can use the Stack class, but note that it is considered legacy. It's synchronized and thread-safe, which can be slower in  single-threaded applications like doing data structures and CP problems. A modern and more efficient alternative is ArrayDeque or LinkedList.
            Java
    import java.util.*;
class Geeks {
    public static void main(String[] args) {
       
        ArrayDeque<String> dequeStack = new ArrayDeque<>();
        dequeStack.push("g");
        dequeStack.push("f");
        dequeStack.push("h");
        System.out.println("Initial ArrayDeque Stack: " + dequeStack);
        System.out.println("Popped from ArrayDeque: " + dequeStack.pop());
        System.out.println("ArrayDeque Stack after pop: " + dequeStack);
    }
}
OutputInitial ArrayDeque Stack: [h, f, g]
Popped from ArrayDeque: h
ArrayDeque Stack after pop: [f, g]
 Related Posts:
Recommended DSA Problems:
11. Linked List
A Linked List is a linear data structure where each element (node) contains data and a reference to the next node.
            Java
    class Node {
    int data;
    Node next;
    Node(int d) {
        data = d;
        next = null;
    }
}
class Main {
    public static void main(String[] args){
        
        Node head = new Node(10);
        head.next = new Node(20);
        head.next.next = new Node(30);
        Node temp = head;
        while (temp != null) {
            System.out.print(temp.data + " ");
            temp = temp.next;
        }
    }
}
Related Posts:
Recommended DSA Problems:
12. Tree
A Tree is a hierarchical data structure with nodes connected by edges. The top node is the root.
            Java
    class Node {
    int data;
    Node left, right;
    Node(int val) {
        data = val;
        left = right = null;
    }
}
class Main {
    static void inorder(Node root)
    {
        if (root == null) return;
        inorder(root.left);
        System.out.print(root.data + " ");
        inorder(root.right);
    }
    public static void main(String[] args){
        
        Node root = new Node(1);
        root.left = new Node(2);
        root.right = new Node(3);
        root.left.left = new Node(4);
        inorder(root);
    }
}
Related Posts:
Recommended DSA Problems:
13. Heap
A Heap is a special tree-based structure that satisfies the heap property (Min-Heap or Max-Heap). In Java, we can use PriorityQueue.
            Java
    import java.util.*;
class Geeks
{
    public static void main(String[] args){
        
        PriorityQueue<Integer> minHeap = new PriorityQueue<>();
        minHeap.add(5);
        minHeap.add(7);
        minHeap.add(9);
        minHeap.add(1);
        System.out.println("Heap: " + minHeap);
        System.out.println("Smallest element: " + minHeap.poll());
        System.out.println("Heap after poll: " + minHeap);
    }
}
OutputHeap: [1, 5, 9, 7]
Smallest element: 1
Heap after poll: [5, 7, 9]
 Related Posts:
Recommended DSA Problems:
14. Graphs
A Graph consists of nodes (vertices) connected by edges. It can be represented in Java using an adjacency list.
            Java
    import java.util.ArrayList;
import java.util.List;
public class GfG {
    
    // Method to add an edge between two vertices
    public static void addEdge(List<List<Integer>> adj, int i, int j) {
        adj.get(i).add(j);
        adj.get(j).add(i); // Undirected
    }
    // Method to display the adjacency list
    public static void displayAdjList(List<List<Integer>> adj) {
        for (int i = 0; i < adj.size(); i++) {
            System.out.print(i + ": "); // Print the vertex
            for (int j : adj.get(i)) {
                System.out.print(j + " "); // Print its adjacent 
            }
            System.out.println(); 
        }
    }
    // Main method
    public static void main(String[] args) {
      
        // Create a graph with 4 vertices and no edges
        int V = 4;
        List<List<Integer>> adj = new ArrayList<>(V); 
        for (int i = 0; i < V; i++) {
            adj.add(new ArrayList<>());
        }
        // Now add edges one by one
        addEdge(adj, 0, 1);
        addEdge(adj, 0, 2);
        addEdge(adj, 1, 2);
        addEdge(adj, 2, 3);
        System.out.println("Adjacency List Representation:");
        displayAdjList(adj);
    }
}
OutputAdjacency List Representation:
0: 1 2 
1: 0 2 
2: 0 1 3 
3: 2 
 Related Posts:
Recommended DSA Problems:
15. Dynamic Programming (DP)
DP is used when problems have overlapping subproblems and optimal substructure. Example: Fibonacci series using DP.
            Java
    class Main {
    
    static int fib(int n, int[] dp) {
        if (n <= 1) return n;
        if (dp[n] != -1) return dp[n];
        return dp[n] = fib(n - 1, dp) + fib(n - 2, dp);
    }
    
    public static void main(String[] args) {
        
        int n = 10;
        int[] dp = new int[n+1];
        java.util.Arrays.fill(dp, -1);
        System.out.println("Fibonacci(" + n + "): " + fib(n, dp));
    }
}
Related Posts:
Recommended DSA Problems:
                                
                                
                            
                                                                                
                                                            
                                                    
                                                
                                                        
                            
                        
                                                
                        
                                                                                    
                                                                Explore
                                    
                                        DSA Fundamentals
Data Structures
Algorithms
Advanced
Interview Preparation
Practice Problem