Collections Framework
Collections framework provides a standard set of interfaces and classes to store and process data efficiently. like a well-organized toolkit for handling groups of items, without having to create these data structures from scratch.
java.util includes one of Java’s most powerful subsystems: the Collections Framework.
The Java Collections Framework is a unified architecture for representing and manipulating collections, which are groups of objects.
All major interfaces like List, Set, and Queue extend from Collection.
Advantages of the Collections Framework
The framework was designed with the following key goals:
High Performance: Core implementations (e.g., ArrayList, LinkedList, HashSet, TreeMap) are highly optimized for performance. Better than Custom implementations.
Unified Architecture: Collections are designed to operate in a similar, consistent manner, enabling interoperability between different types. All classes share common interfaces, different types of collections can work together seamlessly.
Ease of Extension: The architecture allows easy extension or adaptation for new data structures.
An iterator provides a standard way to traverse elements in a collection. All collections implement the
Iterableinterface, enabling the use of enhancedfor-eachloops.The
Collectionsutility class provides algorithms such as sorting, reversing, shuffling, and binary search as static methods that operate on collection objects.
Reduces Programming Effort: It provides powerful, ready-to-use data structures and algorithms, which can be directly used.
Promotes Code Reusability: It establishes a common language for passing collections around, making code easier to understand, maintain, and reuse.
Key Interfaces
The framework is built around a core set of interfaces. Each interface defines a specific type of collection.
1. The Collection Interface
This is the root interface of the hierarchy. It represents a simple group of objects, known as elements. It defines the most basic methods that all collections share, such as add(), remove(), size(), and contains().
The List, Set, and Queue interfaces extend this one.
2. The List Interface
A List is an ordered collection that can contain duplicate elements. It's like a standard array but with dynamic sizing. Elements can be accessed by their integer index.
- Common Implementations:
ArrayList,LinkedList.
3. The Set Interface
A Set is a collection that cannot contain duplicate elements. It models the mathematical concept of a set. There is no concept of order in most Set implementations.
- Common Implementations:
HashSet,LinkedHashSet,TreeSet.
4. The Queue Interface
A Queue is a collection used to hold elements before processing. Queues typically order elements in a First-In, First-Out (FIFO) manner. It's like a line of people waiting for a service.
- Common Implementations:
LinkedList,PriorityQueue.
5. The Map Interface
The Map interface is unique because it doesn't extend the Collection interface. Instead of storing single elements, it stores key-value pairs. Each key must be unique, and it's used to retrieve the corresponding value. It's like a dictionary or a phone book.
- Common Implementations:
HashMap,TreeMap,LinkedHashMap.
| Interface | Description |
|---|---|
| Collection | The root interface. Enables to work with group of objects. All other collection interfaces extend this. |
| List | An ordered collection (sequence). Allows duplicate elements. |
| Set | A collection that contains no duplicate elements. |
| SortedSet | A Set that maintains elements in ascending order. |
| NavigableSet | Extends SortedSet to support navigation methods for closest-match retrievals. |
| Queue | A collection for handling special type of lists typically for removing in FIFO order. (holding elements prior to processing) |
| Deque | A double-ended queue that allows insertion and removal from both ends. |
ArrayList
Core Methods from List Interface Include
boolean add(E element)
boolean remove(Object element)
boolean contains(Object element)
int size()
void clear()
boolean isEmpty()
Iterator<E> iterator()
Object[] toArray()
<T> T[] toArray(T[] a)add(int index, E element)
get(int index)
set(int index, E element)
indexOf(Object element)
remove(Object element)
remove(index)ArrayList Operations and Use Cases
Creating an ArrayList, adding elements, accessing them by index, removing them, and iterating through the list.
import java.util.ArrayList;
public class ArrayListDemo {
public static void main(String[] args) {
// An ArrayList of Strings
ArrayList<String> fruits = new ArrayList<>();
// Add elements
fruits.add("Apple"); // Add to the end
fruits.add("Banana");
fruits.add("Mango");
fruits.add(1, "Orange"); // Add at a specific index
System.out.println("Current list: " + fruits);
// Access elements
String secondFruit = fruits.get(1); // Get element at index 1
System.out.println("The second fruit is: "
+ secondFruit);
System.out.println("The list contains 'Apple': "
+ fruits.contains("Apple"));
System.out.println("The size of the list is: "
+ fruits.size());
// Remove elements
fruits.remove("Banana"); // Remove by object value
fruits.remove(0); // Remove by index
System.out.println("List after removals: "
+ fruits);
// Iterate through the list
System.out.println("\n--- Iterating through the list ---");
for (String fruit : fruits) {
System.out.println("- " + fruit);
}
// Clear the entire list
fruits.clear();
System.out.println("\nList after clearing: "
+ fruits);
System.out.println("Is the list empty? "
+ fruits.isEmpty());
}
}Current list: [Apple, Orange, Banana, Mango]
The second fruit is: Orange
The list contains 'Apple': true
The size of the list is: 4
List after removals: [Orange, Mango]
--- Iterating through the list ---
- Orange
- Mango
List after clearing: []
Is the list empty? trueWhen to Use an ArrayList
An ArrayList is internally backed by a standard array. This structure makes it the preferred choice in the following scenarios:
Frequent Random Access: When the primary need is to access elements by their index (e.g.,
list.get(5)),ArrayListis extremely fast. This operation takes constant time, or O(1).Stable Data with Few Insertions/Deletions: If the list doesn't change much after it's created,
ArrayListis ideal.Adding/Removing at the End: Adding or removing elements at the end of the list is generally efficient.
You should avoid ArrayList when you have many insertions or deletions in the middle of the list. Removing an element from the middle requires shifting all subsequent elements, which is a slow operation (O(n)). In such cases, a LinkedList is a better choice.
Obtaining an Array from an ArrayList
Standard, type-safe method for converting an ArrayList into a regular Java array using the toArray(T[] a) method.
import java.util.*;
class ArrayListToArray {
public static void main(String[] args) {
ArrayList<Integer> al = new ArrayList<Integer>();
// Add elements
al.add(1);
al.add(2);
al.add(3);
al.add(4);
System.out.println("Contents of al: " + al);
System.out.println("Size of al: " + al.size()
+ " " + al.getClass().getName());
// Convert to array
Integer[] ia = new Integer[al.size()];
ia = al.toArray(ia);
System.out.println("Size of al: " + ia.size()
+ " " + ia.getClass().getName());
// Sum array elements
int sum = 0;
for (int i : ia)
sum += i;
System.out.println("Sum is: " + sum);
System.out.println('Array Operation: '
+ ia[0] );
}
}Contents of al: [1, 2, 3, 4]
size: 4
java.util.ArrayList
java.lang.Integer
Sum is: 10
Array Operation: 1<T> T[] toArray(T[] array)
Returns an array containing all elements in the collection, using the specified array as the destination. If the array is too small, a new array is created; if it's larger, the element after the last is set tonull.
