My simple library

..of useful code



Chapters

Java Data Structures

1. ArrayList

The main advantage of ArrayList is that, unlike normal arrays, we don’t need to mention the size when creating one. It automatically adjusts its capacity as elements are added or removed. It may be slower than standard arrays, but it is helpful when the size is not known in advance. Note that creating a large fixed-sized array would cause a waste of space.

Since ArrayList is part of the collections framework, it has better interoperability with other collections. For example, conversion to a HashSet is straightforward. With generics, ArrayList<T> ensures type safety at compile-time.

CopyOnWriteArrayList: This class implements the list interface. It is an enhanced version of ArrayList in which all modifications (add, set, remove, etc.) are implemented by making a fresh copy of the list.

Key Points:

  • Resizable Array or Growable Array.
  • Duplicates are allowed.
  • Insertion order is preserved.
  • Heterogeneous objects are allowed.
  • Null insertion is possible.

2. Vector

The Vector class implements a growable array of objects. Although it falls under legacy classes, it is fully compatible with the collections framework and is found in the java.util package.

Highlights:

  • All methods are synchronized, making it thread-safe (suitable for multi-threaded environments but with performance overhead in single-threaded scenarios).
  • Allows null elements.
  • Provides backward compatibility with the Enumeration interface for iterating over elements.
  • Maintains insertion order like an ArrayList.

Additional Info: The iterators returned by Vector are fail-fast (throwing ConcurrentModificationException upon concurrent modifications).

3. Stack

The Stack class, provided by the Java Collection Framework, models a stack data structure based on LIFO (last-in-first-out). It extends Vector and provides additional operations specific to stack behavior.

Operations include: push, pop, peek, empty, and search.

4. Set

The Set interface, present in the java.util package, is an unordered collection of objects that does not allow duplicate values. It implements the mathematical set concept.

Key Characteristics:

  • No specific order (except in implementations like LinkedHashSet and TreeSet).
  • Allows one null element (in most cases).
  • Implementation classes include HashSet, LinkedHashSet, and TreeSet.
  • For thread safety, alternatives like ConcurrentSkipListSet or Collections.synchronizedSet() can be used.

5. EnumSet

EnumSet is a specialized set implementation for enum types. Part of the java.util package, it provides a highly optimized set for storing enum constants.

Key Details:

  • Extends AbstractSet and implements the Set interface.
  • Not synchronized.
  • Much faster than HashSet.
  • All elements must come from a single enum type.
  • Does not allow null objects (throws NullPointerException if inserted).
  • Uses a fail-safe iterator.

6. HashSet

HashSet implements the Set interface and is used to store unique elements without maintaining any specific order.

Key Points:

  • Can store null values.
  • Uses a HashMap internally.
  • Implements Serializable and Cloneable.
  • Not thread-safe (requires external synchronization if needed).

7. LinkedHashSet

LinkedHashSet combines the uniqueness of a HashSet with the predictable iteration order of a LinkedList by maintaining a doubly-linked list of its elements.

Highlights:

  • Stores unique elements only.
  • Maintains insertion order.
  • Faster iteration compared to HashSet.
  • Allows null elements.

8. SortedSet

The SortedSet interface (in java.util) extends Set and ensures that its elements are stored in a sorted (ascending) order.

Features:

  • Elements are automatically sorted in ascending order.
  • Allows a custom order using a Comparator.
  • Ensures uniqueness of elements.
  • Typically does not allow null elements when natural ordering is used.

9. NavigableSet

NavigableSet is a subtype of SortedSet that provides navigation methods such as first(), last(), headSet(), tailSet(), etc.

It allows both ascending and descending order iteration. The most common implementation is TreeSet.

10. TreeSet

TreeSet implements the SortedSet interface using a self-balancing binary search tree (red–black tree). It maintains elements in sorted order based on natural ordering or via a provided Comparator.

Details:

  • Does not allow duplicate elements.
  • Does not allow null values (throws NullPointerException).
  • Implements the NavigableSet interface with additional navigation methods (higher(), lower(), ceiling(), and floor()).
  • Not thread-safe; requires external synchronization if used concurrently.
  • Efficient operations: add, remove, and search in O(log N) time; printing all elements takes O(N) time.

Note on Synchronized TreeSet: To synchronize, wrap the set with Collections.synchronizedSortedSet() at creation time.

11. PriorityQueue

The PriorityQueue class processes elements according to their natural ordering or via a provided Comparator rather than strictly FIFO.

Highlights:

  • Based on a priority heap.
  • No null elements allowed (throws NullPointerException).
  • Dynamic size that adjusts as needed.
  • Operations like add and poll are O(log n).
  • Not thread-safe; use PriorityBlockingQueue for concurrent environments.

Example Code:

public class Main {
    public static void main(String[] args) {
        // Priority Queue (Min-Heap)
        PriorityQueue p = new PriorityQueue<>();
        p.add(3);
        p.add(10);
        p.add(7);
        p.add(2);
        System.out.println("Head of Queue : " + p.peek());
    }
}
            

Output: Head of Queue : 2

12. TreeMap

TreeMap is part of the Java Collections Framework and implements both the Map and NavigableMap interfaces. It stores key-value pairs in sorted order using a red–black tree.

Key Details:

  • Keys are always sorted (natural ordering or via a custom Comparator).
  • Operations like get, put, and remove run in O(log n) time.
  • Does not allow null keys (null values are allowed).
  • Not synchronized by default.
  • Iterators are fail-fast.

Internal Structure: Each node has key, value, color, and references to left, right, and parent.

13. HashMap

The HashMap class provides the basic implementation of the Map interface using key-value pairs. It uses hashing for efficient retrieval.

Characteristics:

  • Internally uses an array of nodes.
  • Allows one null key and multiple null values.
  • Not ordered (insertion order is not preserved).
  • Not thread-safe.
  • Provides nearly constant-time performance for get and put operations.

Internal Structure: Each node contains an integer hash, key, value, and a pointer to the next node.

14. Hashtable

The Hashtable class implements a hash table that maps keys to values. It is similar to HashMap but is synchronized.

Key Points:

  • Does not support null keys or values.
  • The default capacity is 11 with a load factor of 0.75.
  • Uses hashCode() and equals() for storing and retrieving objects.
  • Uses an array of buckets; collisions are resolved with lists.
  • Provides Enumeration (non-fail-fast).

Advantages: Thread-safe and simple to use.

Disadvantages: Considered obsolete, offers limited functionality, and can have poorer performance compared to newer Map implementations.

15. SortedMap

SortedMap is an interface in the Java Collections Framework that represents a map which maintains its keys in a sorted order.

Details:

  • Keys are stored in natural order (if they implement Comparable) or by a custom Comparator.
  • Main implementation is TreeMap.
  • Does not allow null keys or values (throws error if inserted).

With generics, SortedMap becomes type-safe.

16. ConcurrentHashMap

ConcurrentHashMap is a thread-safe implementation of the Map interface. It allows concurrent read and write operations without locking the entire map.

Features:

  • Divides the map into segments for fine-grained locking.
  • Supports atomic operations such as putIfAbsent(), replace(), and remove().
  • Default concurrency level is 16.
  • Does not allow null keys or values.

17. EnumMap

EnumMap is a specialized implementation of the Map interface for use with enumeration types. It is highly efficient and compact.

Key Features:

  • All keys must be of a single enum type.
  • Maintains natural order of enum constants (the order they are declared).
  • Does not allow null keys (throws NullPointerException if attempted).
  • Iterators are weakly consistent (will not throw ConcurrentModificationException).
  • Internally represented as arrays.

Example Code:

enum Day {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

public class Geeks {
    public static void main(String[] args) {
        EnumMap dayMap = new EnumMap<>(Day.class);
        dayMap.put(Day.MONDAY, "Start of the week");
        dayMap.put(Day.FRIDAY, "End of the week");
        dayMap.put(Day.SUNDAY, "Weekend");
        for (Day day : dayMap.keySet()) {
            System.out.println(day + ": " + dayMap.get(day));
        }
    }
}
            

18. Map.Entry

The Map.Entry interface provides methods to access and manipulate key-value pairs within a Map. It is often used in conjunction with the entrySet() method.

19. Map

The Map interface, part of java.util, represents a mapping between keys and values. It is not a subtype of Collection and behaves differently than other collection types.

Key Characteristics:

  • No duplicate keys; each key maps to at most one value.
  • Allows one null key (in implementations like HashMap and LinkedHashMap) and multiple null values.
  • Iteration order depends on the implementation (e.g., TreeMap and LinkedHashMap have predictable orders, while HashMap does not).

20. LinkedHashMap

LinkedHashMap implements the Map interface and maintains the insertion order of its key-value pairs. It combines the benefits of HashMap with predictable iteration.

Highlights:

  • Stores unique key-value pairs.
  • Maintains insertion order.
  • Allows one null key and multiple null values.
  • Faster iteration than HashMap.

21. NavigableMap

NavigableMap is an extension of the SortedMap interface that provides additional navigation methods for dealing with keys. It supports finding entries for keys that are less than, greater than, or equal to a given key.

Methods include: lowerKey(), higherEntry(), floorEntry(), ceilingEntry(), and submap methods (subMap(), headMap(), tailMap()).

22. ArrayDeque

The ArrayDeque class is a resizable array implementation of the Deque interface. It supports element insertion and removal at both ends and can be used as both a stack (LIFO) and a queue (FIFO).

Key Features:

  • Dynamically resizes.
  • Provides constant-time performance for add and remove operations at both ends.
  • Generally faster than LinkedList due to the absence of node overhead.
  • Not thread-safe by default (use Collections.synchronizedDeque for concurrent access).

Example Code:

public class Geeks {
    public static void main(String[] args) {
        Deque d = new ArrayDeque<>();
        d.addFirst(1);
        d.addLast(2);
        int f = d.removeFirst();
        int l = d.removeLast();
        System.out.println("First: " + f + ", Last: " + l);
    }
}
            

23. Queue

The Queue interface, present in java.util, stores and processes elements in a FIFO (First-In-First-Out) order. It limits insertions to the end of the list and deletions from the start.

Key Points:

  • No null elements (in most implementations).
  • Common implementations: LinkedList, PriorityQueue, ArrayDeque, and ConcurrentLinkedQueue.
  • Used for task scheduling, message passing, and buffer management.
  • Iteration order depends on the specific implementation.

Example Code:

public class QueueCreation {
    public static void main(String args[]) {
        // Create a Queue of Integers using LinkedList
        Queue q = new LinkedList<>();
        System.out.println("Queue elements: " + q);
    }
}