Java Core

Java Collection Framework

  • What is the Java Collection Framework (JCF)?

    • A unified architecture for storing, retrieving, and manipulating groups of objects.
    • Provides interfaces (e.g., List, Set, Map), implementations (e.g., ArrayList, HashSet, HashMap), algorithms (e.g., sorting, searching), and utility classes (e.g., Collections, Arrays).
  • Why is the Collection Framework Needed?

    • Traditional Arrays: Fixed size, can't store objects and primitives in a unified way, no built-in sorting/search, no hierarchy, and not type-safe (before generics).
    • Collections: Dynamic sizing, store objects of any type, built-in utilities, structured via interfaces, and generics enabled.
  • Benefits of the Collection Framework:

    • Reusable and extensible APIs.
    • Reduces coding effort.
    • Increases performance.
    • Supports polymorphism.
    • Standardized data structures.
  • Collection Framework Hierarchy

    • Iterable (interface)
      • Collection (interface)
        • List (interface): ArrayList, LinkedList, Vector, Stack
        • Set (interface): HashSet, LinkedHashSet, TreeSet
        • Queue (interface): PriorityQueue, Deque(Interface)
    • Map (interface, not part of Collection): HashMap, TreeMap, LinkedHashMap, Hashtable, IdentityHashMap, WeakHashMap, ConcurrentHashMap
  • Core Interfaces

    • Collection: Root interface for most collections (except Map). Extended by List, Set, Queue.
    • List: Ordered, allows duplicates, index-based access. Implementations: ArrayList, LinkedList, Vector, Stack.
    • Set: No duplicates, unordered (except LinkedHashSet). Implementations: HashSet, LinkedHashSet, TreeSet.
    • Queue: Designed for holding elements before processing. Implementations: PriorityQueue, Deque, LinkedList.
    • Map: Stores key-value pairs, no duplicate keys. Implementations: HashMap, LinkedHashMap, TreeMap, Hashtable, IdentityHashMap, WeakHashMap, ConcurrentHashMap.
  • Key Implementations and Features

    • ArrayList: List, ordered, allows duplicates, allows null, not thread-safe.
    • LinkedList: List, ordered, allows duplicates, allows null, not thread-safe.
    • HashSet: Set, unordered, no duplicates, allows null, not thread-safe.
    • LinkedHashSet: Set, ordered, no duplicates, allows null, not thread-safe.
    • TreeSet: Set, sorted, no duplicates, no null, not thread-safe.
    • HashMap: Map, unordered, no duplicate keys, allows one null key and multiple null values, not thread-safe.
    • LinkedHashMap: Map, ordered, no duplicate keys, allows one null key and multiple null values, not thread-safe.
    • TreeMap: Map, sorted, no duplicate keys, no null keys, allows null values, not thread-safe.
    • Stack: List, LIFO (Last In First Out), ordered, allows duplicates, allows null, thread-safe (legacy).
    • PriorityQueue: Queue, sorted, allows duplicates, allows null, not thread-safe.
      Vector: List, ordered, allows duplicates, allows null , thread-safe(using intrinsic lock), legacy.
      CopyOnWirteArrayList: List, ordered, allows duplicates, allows null, thread-safe.
  • Utility Classes

    • Collections: Static methods for operations on collections (sort, reverse, min, max, synchronizedList, etc.).
  • Generics in Collections

    • Ensures type safety and no casting needed.
  • Comparable vs Comparator

    • Comparable: Defines natural order inside the class.
    • Comparator: Defines custom order outside the class.
    • Collections.sort(list, new MyComparator());
  • Fail-Fast vs Fail-Safe

    • Fail-Fast: Throws ConcurrentModificationException (e.g., ArrayList, HashMap).
    • Fail-Safe: Safe for concurrency, doesn't throw ConcurrentModificationException (e.g., CopyOnWriteArrayList, ConcurrentHashMap).
  • Real-Time Use Cases

    • List: Shopping cart, playlists.
    • Set: Unique email IDs, roles.
    • Queue: Task scheduling, printer jobs.
    • Map: Caching, dictionary, session storage.
  • ArrayList

    • Internal Structure:
      • Uses an Object[] array called elementData.
      • Starts with default capacity = 10 (if not specified).
    • Resizing Mechanism:
      • When capacity is exceeded, the array is resized by 50%.
      • new capacity = old capacity + (old capacity / 2)
    • Visual Representation of Resizing:
      • Before Resize (Size = 10, Capacity = 10)
      • After Adding 11th Element (Size = 11, Capacity = 15)
    • Actual Code Extract:
      • java private void grow(int minCapacity) { int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); // 1.5x growth if (newCapacity - minCapacity < 0) newCapacity = minCapacity; elementData = Arrays.copyOf(elementData, newCapacity); }
    • Resizing Growth Pattern:
      • Initial: Capacity 10
      • 1st Resize: 10 -> 15
      • 2nd Resize: 15 -> 22
      • 3rd Resize: 22 -> 33
      • 4th Resize: 33 -> 49
    • Why Resizing Is Costly:
      • Each resize operation involves allocating a new array and copying all old elements to the new array.
    • Adding elements one-by-one in a loop can be expensive if you don’t know the final size in advance.
    • Important ArrayList Methods with Examples
      • add(E e) – Adds element to the end: list.add(