JAVA COLLECTIONS FRAMEWORK
Provides a set of interfaces and classes to
implement various data structures and algorithms.
Interfaces of Collections FrameWork
Java Collection Interface
The Collection interface is the root interface of the
collections framework hierarchy.
Java does not provide direct implementations of
the Collection interface
But provides implementations of its subinterfaces
like List, Set, and Queue.
Collections Framework Vs. Collection Interface
People often get confused between the collections
framework and Collection Interface.
The Collection interface is the root interface of the
collections framework.
The framework includes other interfaces as
well: Map and Iterator. These interfaces may also
have subinterfaces.
Subinterfaces of the Collection Interface
List Interface: The List interface is an ordered
collection that allows us to add and remove
elements like an array.
Set Interface: The Set interface allows us to store
elements in different sets similar to the set in
mathematics. It cannot have duplicate elements.
Queue Interface : The Queue interface is used when we want
to store and access elements in First In, First Out manner.
Java Map Interface :
In Java, the Map interface allows elements to be
stored in key/value pairs.
Keys are unique names that can be used to access a
particular element in a map.
Each key has a single value associated with it.
Java Iterator Interface: Provides methods that can be
used to access elements of collections.
Why the Collections Framework?
Provides various data structures and algorithms that
can be used directly.
This has two main advantages:
We do not have to write code to implement these
data structures and algorithms manually.
Our code will be much more efficient as the
collections framework is highly optimized.
Allows us to use a specific data structure for a
particular type of data.
Here are a few examples,
If we want our data to be unique, then we can use
the Set interface provided by the collections
framework.
To store data in key/value pairs, we can use
the Map interface.
The ArrayList class provides the functionality of
resizable arrays.
Java Collection Interface
The Collection interface is the root interface of the
Java collections framework.
There is no direct implementation of this interface.
However, it is implemented through its subinterfaces
like List, Set, and Queue.
For example, the ArrayList class implements
the List interface which is a subinterface of
the Collection Interface.
Subinterfaces of the Collection Interface
List Interface: The List interface is an ordered
collection that allows us to add and remove
elements like an array.
Set Interface: The Set interface allows us to store
elements in different sets similar to the set in
mathematics. It cannot have duplicate elements.
Queue Interface : The Queue interface is used when we want
to store and access elements in First In, First Out manner.
Methods of Collection
The Collection interface includes various methods
that can be used to perform different operations on
objects.
These methods are available in all its subinterfaces.
1. add() - inserts the specified element to the
collection
2. size() - returns the size of the collection
3. remove() - removes the specified element from the
collection
4. iterator() - returns an iterator to access elements of
the collection
5. addAll() - adds all the elements of a specified
collection to the collection
6. removeAll() - removes all the elements of the
specified collection from the collection
7. clear() - removes all the elements of the collection
Java List
The List interface is an ordered collection that allows us to
store and access elements sequentially.
It extends the Collection interface.
Classes that Implement List
Since List is an interface, we cannot create objects from it.
In order to use the functionalities of the List interface, we
can use these classes:
1. ArrayList
2. LinkedList
3. Vector
4. Stack
These classes are defined in the Collections
framework and implement the List interface.
How to use List?
In Java, we must import java.util.List package in
order to use List.
// ArrayList implementation of List
List<String> list1 = new ArrayList<>();
// LinkedList implementation of List
List<String> list2 = new LinkedList<>();
Methods of List
The List interface includes all the methods of
the Collection interface. Its because Collection is a
super interface of List.
Commonly used methods of the Collection interface
that's also available in the List interface are:
add() - adds an element to a list
addAll() - adds all elements of one list to another
get() - helps to randomly access elements from lists
iterator() - returns iterator object that can be used to
sequentially access elements of lists
set() - changes elements of lists
remove() - removes an element from the list
removeAll() - removes all the elements from the list
clear() - removes all the elements from the list (more
efficient than removeAll())
size() - returns the length of lists
toArray() - converts a list into an array
contains() - returns true if a list contains specific element
1. Implementing the ArrayList
Class
import java.util.List; Output
import java.util.ArrayList;
class Main {
public static void main(String[] args) { List: [1, 2, 3]
// Creating list using the ArrayList class
List<Integer> numbers = new ArrayList<>(); Accessed Element: 3
// Add elements to the list Removed Element: 2
numbers.add(1);
numbers.add(2);
numbers.add(3);
System.out.println("List: " + numbers);
// Access element from the list
int number = numbers.get(2);
System.out.println("Accessed Element: " + number);
// Remove element from the list
int removedNumber = numbers.remove(1);
System.out.println("Removed Element: " + removedNumber);
}
}
Implementing the LinkedList Class
import java.util.List;
import java.util.LinkedList; Output
class Main {
public static void main(String[] args) {
List: [1, 2, 3]
// Creating list using the LinkedList class Accessed Element: 3
List<Integer> numbers = new LinkedList<>();
// Add elements to the list Position of 3 is 1
numbers.add(1); Removed Element: 2
numbers.add(2);
numbers.add(3);
System.out.println("List: " + numbers);
// Access element from the list
int number = numbers.get(2);
System.out.println("Accessed Element: " + number);
// Using the indexOf() method
int index = numbers.indexOf(2);
System.out.println("Position of 3 is " + index);
// Remove element from the list
int removedNumber = numbers.remove(1);
System.out.println("Removed Element: " + removedNumber);
}
Java List vs. Set
Both the List interface and the Set interface inherit
the Collection interface. However, there exists some
difference between them.
Lists can include duplicate elements. However, sets
cannot have duplicate elements.
Elements in lists are stored in some order. However,
elements in sets are stored in groups like sets in
mathematics.
Java ListIterator Interface
The ListIterator interface of the Java collections
framework provides the functionality to access
elements of a list.
It is bidirectional. This means it allows us to iterate
elements of a list in both the direction.
It extends the Iterator interface.
The List interface provides a
listIterator() method that returns
an instance of the ListIterator
interface.
Methods of ListIterator
hasNext() - returns true if there exists an element in the list
next() - returns the next element of the list
nextIndex() returns the index of the element that the next()
method will return
previous() - returns the previous element of the list
previousIndex() - returns the index of the element that the
previous() method will return
remove() - removes the element returned by either next() or
previous()
set() - replaces the element returned by either next() or
previous() with the specified element
Implementation of ListIterator
import java.util.ArrayList;
import java.util.ListIterator; OUTPUT:
class Main { ArrayList: [1, 3, 2]
public static void main(String[] args) { Next Element: 1
// Creating an ArrayList Position of Next Element: 1
ArrayList<Integer> numbers = new ArrayList<>(); Is there any next element? true
numbers.add(1);
numbers.add(3);
numbers.add(2);
System.out.println("ArrayList: " + numbers);
// Creating an instance of ListIterator
ListIterator<Integer> iterate = numbers.listIterator();
// Using the next() method
int number1 = iterate.next();
System.out.println("Next Element: " + number1);
// Using the nextIndex()
int index1 = iterate.nextIndex();
System.out.println("Position of Next Element: " + index1);
// Using the hasNext() method
System.out.println("Is there any next element? " + iterate.hasNext());
}
}
Java ArrayList
In Java, we use the ArrayList class to implement the
functionality of resizable-arrays.
It implements the List interface of the collections
framework.
Java ArrayList Vs Array
In Java, we need to declare the size of
an array before we can use it. Once the size of an
array is declared, it's hard to change it.
To handle this issue, we can use the ArrayList class. It
allows us to create resizable arrays.
Unlike arrays, arraylists can automatically adjust
their capacity when we add or remove elements
from them. Hence, arraylists are also known
as dynamic arrays.
Create ArrayList in Java
import java.util.ArrayList;
class Main {
public static void main(String[] args){
// create ArrayList
ArrayList<String> languages = new ArrayList<>();
// Add elements to ArrayList
languages.add("Java");
languages.add("Python");
languages.add("Swift");
System.out.println("ArrayList: " + languages);
}
}
OUTPUT: ArrayList: [Java, Python, Swift]
Basic Operations on ArrayList
The ArrayList class provides various methods to
perform different operations on arraylists. We will
look at some commonly used arraylist operations in
this tutorial:
1. Add elements
2. Access elements
3. Change elements
4. Remove elements
1. Add Elements to an ArrayList
import java.util.ArrayList;
class Main {
public static void main(String[] args){
ArrayList<String> languages = new ArrayList<>();
languages.add("Java");
languages.add("C");
languages.add("Python");
System.out.println("ArrayList: " + languages);
}
}
2. Access ArrayList Elements
To access an element from the arraylist, we use
the get() method of the ArrayList class. For example,
import java.util.ArrayList;
class Main {
public static void main(String[] args) {
ArrayList<String> animals = new ArrayList<>();
// add elements in the arraylist
animals.add("Cat");
animals.add("Dog");
animals.add("Cow");
System.out.println("ArrayList: " + animals);
// get the element from the arraylist
String str = animals.get(1);
System.out.print("Element at index 1: " + str);
}
}
OUTPUT:
ArrayList: [Cat, Dog, Cow]
Element at index 1: Dog
3. Change ArrayList Elements
To change elements of the arraylist, we use
the set() method of the ArrayList class.
import java.util.ArrayList;
class Main {
public static void main(String[] args) {
ArrayList<String> languages = new ArrayList<>();
// add elements in the array list
languages.add("Java");
languages.add("Kotlin");
languages.add("C++");
System.out.println("ArrayList: " + languages);
// change the element of the array list
languages.set(2, "JavaScript");
System.out.println("Modified ArrayList: " + languages);
}
}
ArrayList: [Java, Kotlin, C++]
Modified ArrayList: [Java, Kotlin, JavaScript]
4. Remove ArrayList Elements
To remove an element from the arraylist, we can use
the remove() method of the ArrayList class.
import java.util.ArrayList;
class Main {
public static void main(String[] args) {
ArrayList<String> animals = new ArrayList<>();
// add elements in the array list
animals.add("Dog");
animals.add("Cat");
animals.add("Horse");
System.out.println("ArrayList: " + animals);
// remove element from index 2
String str = animals.remove(2);
System.out.println("Updated ArrayList: " + animals);
System.out.println("Removed Element: " + str);
}
}
ArrayList: [Dog, Cat, Horse]
Updated ArrayList: [Dog, Cat]
Removed Element: Horse
Methods of ArrayList Class
size()- Returns the length of the arraylist.
sort()- Sort the arraylist elements.
clone()- Creates a new arraylist with the same element,
size, and capacity.
contains()- Searches the arraylist for the specified element
and returns a boolean result.
ensureCapacity()- Specifies the total element the arraylist
can contain.
isEmpty()- Checks if the arraylist is empty.
indexOf()- Searches a specified element in an arraylist
and returns the index of the element.
Output:
Iterate through an ArrayList
import java.util.ArrayList; ArrayList: [Cow, Cat, Dog]
Accessing individual elements:
class Main {
public static void main(String[] args) { Cow, Cat, Dog,
// creating an array list
ArrayList<String> animals = new ArrayList<>();
animals.add("Cow");
animals.add("Cat");
animals.add("Dog");
System.out.println("ArrayList: " + animals);
// iterate using for-each loop
System.out.println("Accessing individual elements: ");
for (String language : animals) {
System.out.print(language);
System.out.print(", ");
}
}
}
Java Vector vs. ArrayList
In Java, both ArrayList and Vector implements
the List interface and provides the same
functionalities.
However, there exist some differences between
them.
The Vector class synchronizes each individual
operation. This means whenever we want to perform
some operation on vectors, the Vector class
automatically applies a lock to that operation.
It is because when one thread is accessing a vector,
and at the same time another thread tries to access
it, an exception
called ConcurrentModificationException is
generated. Hence, this continuous use of lock for
each operation makes vectors less efficient.
However, in array lists, methods are not
synchronized. Instead, it uses
the Collections.synchronizedList() method that
synchronizes the list as a whole.
import java.util.Vector;
class Main {
Initial Vector: [Dog, Horse, Cat]
public static void main(String[] args) { Removed Element: Horse
Vector<String> animals= new Vector<>(); New Vector: [Dog, Cat]
animals.add("Dog"); Vector after clear(): []
animals.add("Horse");
animals.add("Cat");
System.out.println("Initial Vector: " + animals);
// Using remove()
String element = animals.remove(1);
System.out.println("Removed Element: " + element);
System.out.println("New Vector: " + animals);
// Using clear()
animals.clear();
System.out.println("Vector after clear(): " + animals);
}
}
Java Stack Class
Initial Stack: [Dog, Horse, Cat]
import java.util.Stack;
Removed Element: Cat
class Main {
public static void main(String[] args) {
Stack<String> animals= new Stack<>();
// Add elements to Stack
animals.push("Dog");
animals.push("Horse");
animals.push("Cat");
System.out.println("Initial Stack: " + animals);
// Remove element stacks
String element = animals.pop();
System.out.println("Removed Element: " + element);
}
}
Java PriorityQueue
Unlike normal queues, priority queue elements are
retrieved in sorted order.
Suppose, we want to retrieve elements in the
ascending order. In this case, the head of the
priority queue will be the smallest element. Once
this element is retrieved, the next smallest element
will be the head of the queue.
It is important to note that the elements of a priority
queue may not be sorted. However, elements are
always retrieved in sorted order.
import java.util.PriorityQueue;
class Main {
public static void main(String[] args) {
// Creating a priority queue
PriorityQueue<Integer> numbers = new PriorityQueue<>();
numbers.add(4);
numbers.add(2);
numbers.add(1);
System.out.println("PriorityQueue: " + numbers);
// Using the peek() method
int number = numbers.peek();
System.out.println("Accessed Element: " + number);
}
}
PriorityQueue: [1, 4, 2]
Accessed Element: 1
Java Map Interface
The Map interface of the Java collections
framework provides the functionality of the map
data structure.
In Java, elements of Map are stored
in key/value pairs. Keys are unique values
associated with individual Values.
A map cannot contain duplicate keys. And, each key
is associated with a single value.
We can access and modify values using the keys
associated with them.
In the above diagram, we have values: United
States, Brazil, and Spain. And we have
corresponding keys: us, br, and es.
We can access those values using their
corresponding keys.
Note: The Map interface maintains 3 different sets:
1. the set of keys
2. the set of values
3. the set of key/value associations (mapping).
Classes that implement Map
Since Map is an interface, we cannot
create objects from it.
In order to use the functionalities of the Map interface,
we can use these classes:
1. HashMap
2. EnumMap
3. LinkedHashMap
4. WeakHashMap
5. TreeMap
These classes are defined in the collections framework
and implemented in the Map interface.
Methods of Map
put(K, V) - Inserts the association of a key K
and a value V into the map. If the key is
already present, the new value replaces the
old value.
get(K) - Returns the value associated with the
specified key K. If the key is not found, it
returns null.
Methods of Map
containsKey(K) - Checks if the specified
key K is present in the map or not.
containsValue(V) - Checks if the specified
value V is present in the map or not.
replace(K, V) - Replace the value of the
key K with the new specified value V.
remove(K) - Removes the entry from the
map represented by the key K.
Methods of Map
remove(K, V) - Removes the entry from the map
that has key K associated with value V.
keySet() - Returns a set of all the keys present
in a map.
values() - Returns a set of all the values present
in a map.
entrySet() - Returns a set of all the key/value
mapping present in a map.
Implementing HashMap Class
import java.util.Map;
import java.util.HashMap;
class Main {
public static void main(String[] args) {
// Creating a map using the HashMap
Map<String, Integer> numbers = new HashMap<>();
// Insert elements to the map
numbers.put("One", 1);
numbers.put("Two", 2);
System.out.println("Map: " + numbers);
// Access keys of the map
System.out.println("Keys: " + numbers.keySet());
// Access values of the map
System.out.println("Values: " + numbers.values());
// Access entries of the map
System.out.println("Entries: " + numbers.entrySet());
// Remove Elements from the map
int value = numbers.remove("Two");
System.out.println("Removed Value: " + value);
}
}
OUTPUT:
Map: {One=1, Two=2}
Keys: [One, Two]
Values: [1, 2]
Entries: [One=1, Two=2]
Removed Value: 2
Java Set Interface
The Set interface of the Java Collections framework
provides the features of the mathematical set in
Java. It extends the Collection interface.
Unlike the List interface, sets cannot contain
duplicate elements.
Set Operations
The Java Set interface allows us to perform basic
mathematical set operations like union, intersection, and
subset.
Union - to get the union of two sets x and y, we can use
x.addAll(y)
Intersection - to get the intersection of two sets x and y,
we can use x.retainAll(y)
Subset - to check if x is a subset of y, we can use
y.containsAll(x)
Java HashSet Class
The HashSet class of the Java Collections
framework provides the functionalities of the hash
table data structure.
// HashSet with 8 capacity and 0.75 load factor
HashSet<Integer> numbers = new HashSet<>(8, 0.75);
Notice, the part new HashSet<>(8, 0.75). Here, the first
parameter is capacity, and the second parameter
is loadFactor.
capacity - The capacity of this hash set is 8. Meaning, it
can store 8 elements.
loadFactor - The load factor of this hash set is 0.6. This
means, whenever our hash set is filled by 60%, the
elements are moved to a new hash table of double the
size of the original hash table.
import java.util.HashSet;
class Main {
public static void main(String[] args) {
HashSet<Integer> evenNumber = new HashSet<>();
// Using add() method
evenNumber.add(2);
evenNumber.add(4);
evenNumber.add(6);
System.out.println("HashSet: " + evenNumber);
HashSet<Integer> numbers = new HashSet<>();
// Using addAll() method
numbers.addAll(evenNumber);
numbers.add(5);
System.out.println("New HashSet: " + numbers);
}
}
OUTPUT:
HashSet: [2, 4, 6]
New HashSet: [2, 4, 5, 6]