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)
- Collection (interface)
- Map (interface, not part of Collection): HashMap, TreeMap, LinkedHashMap, Hashtable, IdentityHashMap, WeakHashMap, ConcurrentHashMap
- Iterable (interface)
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).
- Fail-Fast: Throws
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 calledelementData. - Starts with default capacity = 10 (if not specified).
- Uses an
- 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(
- Internal Structure: