Collection Framework in Java


JavaViews 2292

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.

Hierarchy of Java Collections Framework

Collections in Java

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

MethodDescription
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 spliteratorReturns 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

 

Reference

Translate ยป