Java Collections is a framework that represents a group of objects which consists of interfaces and implementation classes. We will discuss the Collection framework, its interfaces, and classes in this tutorial.
In Java, a collection is a single entity that represents a group of objects and a framework is a defined architecture that contains interfaces and classes. Hence, the Java Collection framework is an architecture that defines a set of interfaces, classes, and algorithms. This framework was available from JDK 1.2. It can also perform operations like search, insert, sort, delete, manipulate, etc.
Table of Contents
Hierarchy of Java Collections Framework
Advantages of Java Collections
- Consistent API – The developers can use the existing interface API and does not require extra effort to develop it.
- Reduces programming effort – It reduces the effort to design the data structures since the framework already provides it.
- Increases the code quality and development – It provides high performance
- Provides reusability
Methods of Java Collections
Method | Description |
---|---|
boolean add(E e) | Adds an element to the Collection |
boolean addAll(Collection c) | Adds a collection of elements to the Collection |
void clear() | Clears the collection by deleting all the elements and makes it empty |
boolean contains(Object e) | Returns true if the collection contains the specified element |
boolean containsAll(Collection c) | Returns true if the collection contains all the specified collection elements |
boolean equals(Object o) | Checks if the specified object is equal to the collection element. |
int hashCode() | Returns the hashcode integer value of the collection |
boolean isEmpty() | Checks if the collection is empty |
Iterator iterator() | Returns an iterator over the Collection elements |
Stream parallelStream() | Returns a parallel stream of the collection |
boolean remove(Object e) | Deletes the specified element from the Collections |
boolean removeAll(Collection c) | Removes all the specified collection elements |
boolean removeIf(Predicate filter) | Removes all the elements in the collection that satisfies the predicate |
boolean retainAll(Collection c) | Retains all the specified collection elements and deletes the other elements from the collection |
int size() | Returns the number of elements in the collection |
Stream stream() | Returns a sequential stream of the collection |
Spliterator spliterator | Returns a spliterator over the elements in the Collection |
Object[] toArray() | Converts the collection into an array |
t[] toArray(T[] a) | Converts the collection into an array where the runtime types of the returned array is that of the specified array |
Collections Interfaces
This is the root interface of the Collection framework hierarchy. The other interfaces which are present in the Collection framework are Map and Iterator interfaces. These interfaces further have subinterfaces since there is no direct implementation for the Collection interface.
The Collection interfaces contain List, Set, and Queue interfaces.
List interface
The List interface of the Java Collections maintains the sequential order of the elements and can store duplicate values. We can access and insert the elements from the list based on their index values.
The ArrayList, LinkedList, and Vector are the classes that implement the List interface.
ArrayList
The ArrayList provides dynamic arrays whose size increases or decreases automatically as the Collection grows or shrinks. We can access random elements from the ArrayList based on the index. in order to use ArrayList for primitive data types, we need to use the corresponding wrapper classes like Integer, Character, etc.
import java.util.ArrayList; public class ArrayListDemo2 { public static void main(String[] args) { //Create an Integer ArrayList ArrayList<Integer> numbers = new ArrayList<Integer>(); numbers.add(4); numbers.add(8); numbers.add(2); System.out.println("List elements: "); System.out.println(numbers); //Modify element numbers.set(1, 6); System.out.println("After modifying element at index 1:"); System.out.println(numbers); //Remove an element numbers.remove(2); System.out.println("After removing element at index 2:"); System.out.println(numbers); } }
List elements: [4, 8, 2] After modifying element at index 1: [4, 6, 2] After removing element at index 2: [4, 6]
LinkedList
The LinkedList class is another Collection class that uses the LinkedList data structure. Each element is called a node that contains the value along with pointers to the subsequent elements. These pointers store the address of the next element. The manipulation is faster than ArrayList and maintains the insertion order.
import java.util.Deque; import java.util.LinkedList; public class LinkedListDemo { public static void main(String[] args) { LinkedList<String> cities = new LinkedList<String>(); cities.add("Chennai"); cities.add("Bangalore"); //Inserts element at the beginning cities.push("Kolkata"); System.out.println(cities); //Retrieves first element System.out.println("Output of element() method: " + cities.element()); System.out.println("Out of get method at specified index 2: " + cities.get(2)); //Print and delete the first element System.out.println("Output of pop() method: " + cities.pop()); System.out.println(cities); //Check if list is empty System.out.println("Is LinkedList empty: " + cities.isEmpty()); //Sets new value at index 1 cities.set(1, "Goa"); System.out.println("List elements after using set() method: " + cities); //List size System.out.println("Size of the LinkedList: " + cities.size()); } }
[Kolkata, Chennai, Bangalore] Output of element() method: Kolkata Out of get method at specified index 2: Bangalore Output of pop() method: Kolkata [Chennai, Bangalore] Is LinkedList empty: false List elements after using set() method: [Chennai, Goa] Size of the LinkedList: 2
Vector
Vector was initially a legacy class but later became part of the Collections framework. It also stores a dynamic array but however, it is synchronized. Since it was initially a legacy class, it has its own methods other than the Collections methods.
import java.util.Vector; public class RetrieveVectorElements { public static void main(String[] args) { Vector v = new Vector(); v.add("Welcome"); v.add("to"); v.add("Java"); v.add("programming"); v.add(100); System.out.println("Vector content:" + v); System.out.println("Element at index 2: " + v.elementAt(2)); System.out.println("First element: " + v.firstElement()); System.out.println("Element at index 3: " + v.get(3)); System.out.println("Index of the specified element: " + v.indexOf("Java")); System.out.println("Index of the element from the specified index: " + v.indexOf(100, 1)); System.out.println("Last element: " + v.lastElement()); System.out.println("Last index of the element: " + v.lastIndexOf("programming")); System.out.println("Last index of the element from the specified index: " + v.lastIndexOf("to", 3)); v.set(4,"language"); v.setElementAt("Python", 2); System.out.println("Elements after using set method: " + v); } }
Vector content:[Welcome, to, Java, programming, 100] Element at index 2: Java First element: Welcome Element at index 3: programming Index of the specified element: 2 Index of the element from the specified index: 4 Last element: 100 Last index of the element: 3 Last index of the element from the specified index: 1 Elements after using set method: [Welcome, to, Python, programming, language]
Set interface
The Set interface is another subinterface of the Collection interface and stores unordered elements. This means it does not maintain insertion order and we cannot store duplicate value.
The HashSet, LinkedHashSet, and TreeSet are the classes that implement the Set interface.
HashSet class
The HashSet class uses the hashing technique to store the elements in the Collection. Based on the hashcode value, it stores the elements in the corresponding location. It can store only unique values.
import java.util.*; public class SetArray { public static void main(String[] args) { Set<String> names = new HashSet<String>(); names.add("Roshan"); names.add("Kiran"); names.add("Tejas"); names.add("Karthik"); String[] strnames = names.toArray(new String[names.size()]); for(String strvalues: strnames) { System.out.println(strvalues); } } }
Roshan Kiran Tejas Karthik
LinkedHashSet class
The LinkedHashSet class uses the LinkedList implementation to store data in a Collection. It extends the HashSet class and allows us to store only unique elements. It preserves the insertion order of elements.
import java.util.LinkedHashSet; public class LinkedHashSetDemo { public static void main(String[] args) { LinkedHashSet<String> l = new LinkedHashSet<String>(); l.add("Ravi"); l.add("Rakesh"); l.add("Suresh"); System.out.println(l); } }
[Ravi, Rakesh, Suresh]
TreeSet class
The TreeSet class uses the tree data structure to store its elements in a Collection. It provides natural sorting functionality and hence it’s easy to access the elements faster. By default, all the elements are stored in ascending order.
import java.util.TreeSet; public class TreeSetDemo { public static void main(String[] args) { TreeSet<String> ts = new TreeSet<String>(); ts.add("Bangalore"); ts.add("Chennai"); ts.add("Delhi"); ts.add("Goa"); ts.add("Mysore"); System.out.println("Elements in the TreeSet after add operation:" + ts); ts.remove("Chennai"); System.out.println("Elements in the TreeSet after remove method: " + ts); TreeSet<String> t = new TreeSet<String>(); t.add("Mumbai"); t.add("Hyderabad"); ts.addAll(t); System.out.println("Elements in the TreeSet after addAll operation: " + ts); ts.removeAll(t); System.out.println("Elements in the TreeSet after removeAll method: " + ts); ts.pollFirst(); System.out.println("Elements in the TreeSet after pollFirst method: " + ts); ts.pollLast(); System.out.println("Elements in the TreeSet after pollLast method: " + ts); } }
Elements in the TreeSet after add operation:[Bangalore, Chennai, Delhi, Goa, Mysore] Elements in the TreeSet after remove method: [Bangalore, Delhi, Goa, Mysore] Elements in the TreeSet after addAll operation: [Bangalore, Delhi, Goa, Hyderabad, Mumbai, Mysore] Elements in the TreeSet after removeAll method: [Bangalore, Delhi, Goa, Mysore] Elements in the TreeSet after pollFirst method: [Delhi, Goa, Mysore] Elements in the TreeSet after pollLast method: [Delhi, Goa]
Queue interface
The Queue interface uses the first-in-first-out(FIFO) concept to store and retrieve the elements in the Collection.
The classes that implement the Queue interface are PriorityQueue, Dequeue, and ArrayQueue.
PriorityQueue class
The PriorityQueue processes the elements based on its priority. We cannot store null values in a priorityqueue.
import java.util.PriorityQueue; public class PriorityQueueDemo { public static void main(String[] args) { PriorityQueue<String> p = new PriorityQueue(); p.add("Ravi"); p.add("Rakesh"); p.add("Suresh"); for(String s : p) System.out.println(s); System.out.println("First element: " + p.peek()); } }
Rakesh Ravi Suresh First element: Rakesh
Deque interface
Deque stands for the double-ended queue which means we can insert and remove elements from both sides. It is implemented using the ArrayDeque class. We can create an instance of Deque as below.
Deque d = new ArrayDeque();
ArrayDeque class
ArrayDeque class implements the Deque interface which means we can use the Deque using this class. This enables us to insert and delete elements from both ends. We can create a resizable array and there is no restriction on its capacity.
import java.util.ArrayDeque; import java.util.Deque; public class ArrayDequeDemo { public static void main(String[] args) { Deque<Integer> d = new ArrayDeque<Integer>(); d.add(10); d.add(20); d.add(30); d.add(40); d.add(50); System.out.println(d); d.addFirst(100); d.addLast(200); System.out.println(d); } }
[10, 20, 30, 40, 50] [100, 10, 20, 30, 40, 50, 200]
Iterable interface
This is the parent interface for the Collection interface. The Collection interface extends this interface and hence the other subinterfaces also inherit the Iterable interface and its implementation. The Iterable interface provides an iterator for the Collections elements. It contains an abstract method iterator().
Iterator<T> iterator();
import java.util.Iterator; import java.util.LinkedList; import java.util.Set; import java.util.ArrayList; import java.util.HashSet; public class IteratorExample { public static void main(String[] args) { ArrayList<Integer> age = new ArrayList<Integer>(); LinkedList<String> names = new LinkedList<String>(); Set<String> setnames = new HashSet<String>(); setnames.add("Roshan"); setnames.add("Kiran"); setnames.add("Tejas"); setnames.add("Karthik"); Iterator<String> iterator = setnames.iterator(); while(iterator.hasNext()) System.out.println(iterator.next()); age.add(10); age.add(20); age.add(30); age.add(40); age.add(50); Iterator<Integer> i = age.iterator(); System.out.println("Age:"); while(i.hasNext()) System.out.print(i.next() + " "); } }
Roshan Kiran Tejas Karthik Age: 10 20 30 40 50
Map interface
The Map interface is part of the Collection framework that stores data in the form of key-value pairs. It can store only unique keys and cannot contain duplicates. We can retrieve the values from the map based on the specific key.
The TreeMap, HashMap, and LinkedHashMap are the classes that implement the Map interface.
TreeMap class
It stores elements in the form of a tree data structure and orders the elements based on the values.
import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; public class IterateTreeMap { public static void main(String[] args) { TreeMap<Integer, String> tm = new TreeMap<Integer, String>(); tm.put(111, "Aditya"); tm.put(333, "Bharat"); tm.put(222, "Dev"); tm.put(555, "Hari"); tm.put(444, "Charan"); System.out.println("Iterate using Entry Set:"); for(Map.Entry<Integer,String> m: tm.entrySet()) System.out.println(m.getKey() + " " + m.getValue()); System.out.println("Iterate using KeySet: "); for(Integer i: tm.keySet()) System.out.println(i + " " + tm.get(i)); System.out.println("Iterate through NavigableKeySet: "); System.out.println(tm.navigableKeySet()); } }
Iterate using Entry Set: 111 Aditya 222 Dev 333 Bharat 444 Charan 555 Hari Iterate using KeySet: 111 Aditya 222 Dev 333 Bharat 444 Charan 555 Hari Iterate through NavigableKeySet: [111, 222, 333, 444, 555]
HashMap class
It stores the elements in the form of key-value pair but does not provide any insertion order. This means we cannot retrieve the values in the same order in which it was inserted.
import java.util.HashMap; import java.util.Map; public class IterateHashMap { public static void main(String[] args) { HashMap<String,String> cityState = new HashMap<>(); cityState.put("Bangalore", "Karnataka"); cityState.put("Chennai", "TamilNadu"); cityState.put("Madurai", "TamilNadu"); cityState.put("Mumbai", "Maharashtra"); System.out.println("Display keys:"); for(String s : cityState.keySet()) { System.out.println(s); } System.out.println(); System.out.println("Display values: "); for(String c : cityState.values()) { System.out.println(c); } System.out.println(); System.out.println("Display both key-value pairs:"); for(String v : cityState.keySet()) { System.out.println("Key: " + v + " | value: " + cityState.get(v)); } } }
Display keys: Chennai Madurai Mumbai Bangalore Display values: TamilNadu TamilNadu Maharashtra Karnataka Display both key-value pairs: Key: Chennai | value: TamilNadu Key: Madurai | value: TamilNadu Key: Mumbai | value: Maharashtra Key: Bangalore | value: Karnataka
LinkedHashMap class
It is similar to the HashMap class but the only difference is that LinkedHashMap maintains insertion order. We can retrieve the values in the same order in which it was inserted.
import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; public class IterateLinkedHashMap { public static void main(String[] args) { LinkedHashMap<Integer,String> lh = new LinkedHashMap<Integer,String>(); lh.put(1, "Aarthi"); lh.put(2, "Bharathi"); lh.put(3, "Chandini"); System.out.println("Iterate using EntrySet method: "); for(Map.Entry<Integer, String> m : lh.entrySet()) { System.out.println(m.getKey() + " : " + m.getValue()); } System.out.println("Iterate using the KeySet method: "); for(Integer s : lh.keySet()) { System.out.println(s); } System.out.println("Iterate using the Collection values method: "); for(String val : lh.values()) { System.out.println(val); } } }
Iterate using EntrySet method: 1 : Aarthi 2 : Bharathi 3 : Chandini Iterate using the KeySet method: 1 2 3 Iterate using the Collection values method: Aarthi Bharathi Chandini