Home

 › 

Articles

 › 

Collection Framework In Java Explained, With Examples

Collection Framework in Java

Collection Framework In Java Explained, With Examples

When using an object-oriented programming language, such as Java, you’ll often want to make use of a framework. A framework is a pre-existing library or block of code with a common structure. This allows you to reuse software for several projects, saving you time and effort. One of the most used frameworks is known as the collection framework. We’re going to examine this framework in detail, the classes and interfaces included within it, and what it can be used for.

What is the Collection Framework?

The Collection Framework is a popular framework used with Java. It contains classes and interfaces that are used for working with objects and makes it easier to work with complex data structures, such as arrays, hash tables, and trees. By using the framework, you can avoid the need to manually write out the code for algorithms and data structures, as well as use a specific structure for a particular data type. The main goals of the collection framework are to give a common interface for the most-used methods, increase program speed and reduce the effort required from the programmer.

Collection Framework in Java: The Interfaces

Whereas a class is used to create objects with specific attributes and behaviors, an interface is a sort of contract that dictates methods that a class must implement. As such, an interface provides the “what” for a class, but not the “how”, i.e. the implementation. There are several collection interfaces included in the collection framework. These are:

  • Iterable
  • List
  • Vector
  • Queue
  • Deque
  • Set
  • Map

Let’s take a more detailed look at these interfaces and the classes within each.

Iterable Interface

As the root interface for the whole framework, every interface and class within the framework makes use of the iterable interface. The main purpose of this interface is to provide an iterator for the collections to use, or a way to traverse the elements of a collection. Only one method is present in the iterable interface, which is described as follows:

Iterator<T>iterator().

List Interface

As a subtype of the collection interface, the list interface contains methods to be used on ordered elements. This interface is one of the most used within the Java collection framework. Several classes implement the list interface, including ArrayList, LinkedList, and Vector. These all work on ordered elements and duplicate elements. Methods that can be used within the list interface include add(), remove(), set(), get(), indexOf() lastindexOf() and subList(). List is generally used for searching, sorting, and iterating over a list’s elements. To create an object using one of the classes within the list interface, we write the following code:

List<type of data><list name>= new <class name>()

The data type could be a primitive type like float or int, or an object type like date or string. The class name can be any of the classes, such as ArrayList or LinkedList.

ArrayList

This class provides dynamic arrays, meaning that the size of the list can automatically increase or decrease as objects are added or removed. ArrayList can be implemented as follows:

import java.util.ArrayList;

public class ArrayListExample {
    public static void main(String[] args) {
        ArrayList<String> fruits = new ArrayList<>();

        fruits.add("apple");
        fruits.add("banana");
        fruits.add("orange");

        System.out.println("Fruits: " + fruits);

        int size = fruits.size();
        System.out.println("Size of the ArrayList: " + size);

        String firstFruit = fruits.get(0);
        System.out.println("First fruit: " + firstFruit);

        fruits.remove(1);
        System.out.println("Fruits after removing banana: " + fruits);

        boolean containsApple = fruits.contains("apple");
        System.out.println("Does fruits contain apple? " + containsApple);
    }
}

To start, we’re importing the “ArrayList” class from the collection framework. Then, we created the “ArrayList” list as a string type called “fruits.” Elements are added using the “add()” method. After this, the size is obtained by the “get()” method, and elements are removed with the “remove()” method. Finally, the list is checked for the “apple” element with the “contains()” method. All of these results are printed on the console, as shown in the following screenshot.

Collection Framework in Java
An ArrayList example with its output.

©History-Computer.com

LinkedList

A linked list is a data structure where list elements aren’t contiguous, and are linked with pointers. Each element is known as a node. This is illustrated with our previous fruit example in the following code.

import java.util.LinkedList;

public class LinkedListExample {
    public static void main(String[] args) {
        LinkedList<String> linkedList = new LinkedList<String>();

        linkedList.add("apple");
        linkedList.add("banana");
        linkedList.add("orange");

        for (String fruit : linkedList) {
            System.out.println(fruit);
        }
    }
}

As before, we import a class from the collection framework, which is the “LinkedList” class this time. A linked list of the string type is created, with the same elements as before. A “for” loop is used to iterate over the list, and each element is printed on the console as shown in the image.

Collection Framework in Java
The elements in a LinkedList are called nodes and are linked together.

©History-Computer.com

Vector

The vector class is similar to the array list class concerning implementation but has different properties. While vector is usually slower and the size cannot be increased by a specific amount (the size can only double), vector is synchronized. This means multiple threads can access the class simultaneously, which isn’t possible with an array list. Example code to demonstrate vector is as follows:

import java.util.Vector;

public class VectorExample {
    public static void main(String[] args) {
        Vector<String> fruits = new Vector<String>();

        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Cherry");

        System.out.println("Fruits at index 0: " + fruits.get(0));
        System.out.println("Fruits at index 1: " + fruits.get(1));
        System.out.println("Fruits at index 2: " + fruits.get(2));

        fruits.set(1, "Orange");

        fruits.remove(2);

        System.out.println("Updated Vector: " + fruits);
    }
}

We begin by importing the Vector class, and we add the 3 fruits to the class. Then, we access and update the elements, remove an element, and print the results on the console as illustrated below.

Collection Framework in Java
Multiple threads can access the Vector class at the same time.

©History-Computer.com

Stack

Stack can be thought of as a subclass of vector, and implements the stack data structure. This structure operates on the last-in-first-out principle, meaning the last item to be added will be the first to be removed. This can be useful in situations such as web browsing. The code below shows how to implement the stack class.

import java.util.Stack;

public class StackExample {
    public static void main(String[] args) {
        Stack<String> fruitStack = new Stack<>();
        fruitStack.push("Apple");
        fruitStack.push("Banana");
        fruitStack.push("Cherry");

        System.out.println("Stack: " + fruitStack);

        String poppedFruit = fruitStack.pop();
        System.out.println("Popped fruit: " + poppedFruit);
        System.out.println("Stack after pop: " + fruitStack);

        String topFruit = fruitStack.peek();
        System.out.println("Top fruit: " + topFruit);
        System.out.println("Stack after peek: " + fruitStack);
    }
}

We import the Stack class and create a string type with 3 fruit names using the “push()” method, and the result is printed. The “pop()” method is then used to remove the fruit at the top of the stack, with the updated stack and the popped element printed. Then, the “peek()” method is used to get the fruit at the top without removing it from the stack, and this result is printed as well. See the screenshot below to view the output.

Collection Framework in Java
The implementation of the Stack class with its output.

©History-Computer.com

Queue Interface

The queue interface is another interface within the collection framework in Java. This is used to implement the queue data structure, which operates on the first-in-first-out principle. In this way, the removed element is at the other end of the queue to which an element is added. The most popular way to use the queue interface is through the priority queue class. Let’s look at this with an example code:

import java.util.Queue;

public class QueueExample {

    public static void main(String[] args) {
        
        Queue<String> fruitQueue = new LinkedList<>();
  
        fruitQueue.add("Apple");
        fruitQueue.add("Banana");
        fruitQueue.add("Cherry");

        System.out.println("Fruit Queue: " + fruitQueue);

        String firstFruit = fruitQueue.peek();
        System.out.println("First fruit in queue: " + firstFruit);

        String removedFruit = fruitQueue.remove();
        System.out.println("Removed fruit from queue: " + removedFruit);

        System.out.println("Fruit Queue after removing first element: " + fruitQueue);

        fruitQueue.add("Grapes");

        System.out.println("Fruit Queue after adding a new element: " + fruitQueue);
    }
}

We import the queue class, add 3 fruits to the string, and print. Then, we peek and print the first element, remove the first element and print, and then add a new element and print. See the output below.

Collection Framework in Java
In a Queue, the first-in-first-out principle is followed.

©History-Computer.com

Deque Interface

As a variant of the queue structure, deque is short for double-ended queue. As such, we can add and remove elements from both ends of the queue. This is usually implemented with the array deque class, such as in this code:

import java.util.ArrayDeque;

public class ArrayDequeExample {
    public static void main(String[] args) {
        ArrayDeque<String> fruits = new ArrayDeque<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Cherry");
        fruits.add("Durian");
        
        System.out.println("Fruits in the deque: " + fruits);
        
        String firstFruit = fruits.peekFirst();
        String lastFruit = fruits.peekLast();
        System.out.println("First fruit: " + firstFruit);
        System.out.println("Last fruit: " + lastFruit);
        
        fruits.removeFirst();
        fruits.removeLast();
        System.out.println("Fruits in the deque after removal: " + fruits);
        
        fruits.addFirst("Grape");
        fruits.addLast("Honeydew");
        System.out.println("Fruits in the deque after addition: " + fruits);
    }
}

We create a string type called “fruits” as before, after importing the ArrayDeque class. The output is printed after adding the elements, as well as after peeking the first and last elements. These are then removed and the deque printed. We finish by adding two elements and printing the output as shown below.

Collection Framework in Java
The Deque Interface allows one to access the elements in the list from both sides.

©History-Computer.com

Set Interface

Unlike an array, a set is a collection of unordered objects, where we cannot store duplicate values. The set interface is part of the Java collection framework to implement this structure. All subclasses, including HashSet, TreeSet, and LinkedHashSet, can be instantiated as follows:

Set<type of object><set name> = new <class name>()

Let’s look at each of these subclasses next.

HashSet

This is a subclass used to implement the hash data table structure, where objects are not necessarily in the same order as we inserted them, or non-null values. Consider the following code:

import java.util.HashSet;

public class HashSetExample {
    public static void main(String[] args) {
        HashSet<String> fruitSet = new HashSet<>();

        fruitSet.add("Apple");
        fruitSet.add("Banana");
        fruitSet.add("Cherry");
        fruitSet.add("Date");
        fruitSet.add("Elderberry");

        System.out.println("The size of the set is: " + fruitSet.size());

        if (fruitSet.contains("Apple")) {
            System.out.println("The set contains an Apple");
        }

        fruitSet.remove("Cherry");

        for (String fruit : fruitSet) {
            System.out.println(fruit);
        }

        fruitSet.clear();

        if (fruitSet.isEmpty()) {
            System.out.println("The set is empty");
        }
    }
}

After importing the HashSet class, we add fruits as before and print. Then, we check for a specific element, print, then remove an element, and print the list as shown in the image.

Collection Framework in Java
In a HashSet interface, the data is not necessarily in the same order as we inserted it.

©History-Computer.com

LinkedHashSet

This is similar to HashSet, except a doubly-linked list is used to retain the element order. Code to demonstrate this is next.

import java.util.LinkedHashSet;

public class LinkedHashSetExample {
    public static void main(String[] args) {
        // create a LinkedHashSet of fruits
        LinkedHashSet<String> fruitSet = new LinkedHashSet<String>();

        // add fruits to the set
        fruitSet.add("apple");
        fruitSet.add("banana");
        fruitSet.add("orange");
        fruitSet.add("pear");
        fruitSet.add("grape");

        // print out the set
        System.out.println("Fruits in set: " + fruitSet);

        // attempt to add a duplicate fruit
        boolean duplicateAdded = fruitSet.add("apple");

        // check if the duplicate fruit was added
        if (duplicateAdded) {
            System.out.println("Duplicate fruit added");
        } else {
            System.out.println("Duplicate fruit not added");
        }

        // remove a fruit from the set
        fruitSet.remove("pear");

        // print out the set again
        System.out.println("Fruits in set after removing pear: " + fruitSet);
    }
}

The LinkedHashSet class is imported, and a string is created with 5 fruits. The list is printed, and an element is duplicated and verified. After printing, we remove an element and print again. Check the screenshot for what this looks like.

Collection Framework in Java
The LinkedHashSetExample class with its output.

©History-Computer.com

TreeSet

The TreeSet class uses a tree to store data as nodes with a hierarchical structure. Trees are used to represent structures like organization charts, family trees, and file systems. We can show this with the following code:

import java.util.TreeSet;

public class TreeSetExample {
    public static void main(String[] args) {
        TreeSet<String> fruitSet = new TreeSet<String>();
        fruitSet.add("Apple");
        fruitSet.add("Banana");
        fruitSet.add("Orange");
        fruitSet.add("Pineapple");
        fruitSet.add("Grape");

        System.out.println("Fruits in TreeSet: " + fruitSet);

        // Using methods of TreeSet
        System.out.println("First fruit: " + fruitSet.first());
        System.out.println("Last fruit: " + fruitSet.last());
        System.out.println("Fruits less than Pineapple: " + fruitSet.headSet("Pineapple"));
        System.out.println("Fruits greater than or equal to Pineapple: " + fruitSet.tailSet("Pineapple"));
    }
}

As before, we import the class and then create a string of fruits. After printing, we print the first and last fruits, then print elements less than pineapple and greater to or equal to. In this case, the list is sorted into alphabetical order. The image shows the output.

Collection Framework in Java
In a TreeSet data is stored as nodes with a hierarchical structure.

©History-Computer.com

Map Interface

The last interface in the collection framework is the Map interface, which contains the hash map class. This stores data in key, value pairs. These are often used in databases, as each key refers to a specific value. Using the same example, some code to explain this is below.

import java.util.HashMap;
import java.util.Map;

public class HashMapExample {

    public static void main(String[] args) {
        Map<String, Integer> fruitMap = new HashMap<>();
        fruitMap.put("apple", 1);
        fruitMap.put("banana", 2);
        fruitMap.put("orange", 3);

        System.out.println("Fruit map: " + fruitMap);
        System.out.println("Number of fruits: " + fruitMap.size());

        Integer appleCount = fruitMap.get("apple");
        if (appleCount != null) {
            System.out.println("Number of apples: " + appleCount);
        }

        fruitMap.put("apple", 2); // update the count of apples
        System.out.println("Updated fruit map: " + fruitMap);

        fruitMap.remove("orange"); // remove the orange entry
        System.out.println("Updated fruit map after removing orange: " + fruitMap);
    }
}

An object named “Map” is created that maps string keys to integer values. In this case, the keys are fruit names, and the values are fruit counts. Elements are added with the “put()” method, along with their counts. The fruit map and number are printed, along with the number of apples and the updated map after counting the apples and removing orange.

Collection Framework in Java
In a Map Interface, the data is stored in key, value pairs.

©History-Computer.com

Wrapping Up

The collection framework is a collection of interfaces and classes used for storing and processing data in collections. It helps to make coding more efficient when working with collections of elements. The classes commonly used include ArrayList, LinkedList, Queue, Deque, TreeSet, and HashMap. Overall, the collection framework is an essential tool in a Java programmer’s arsenal for working with objects.

Frequently Asked Questions

What is the collection framework?

The collection framework is a collection of interfaces and classes used in Java to process and store data. Many common implementations are included, such as lists, sets, queues, trees and maps.

Is there a difference between collection and collections?

Yes, collection refers to the root interface of the collection framework, and collections refers to a class that provides methods for functions like searching and sorting.

What is the time complexity of the collection framework?

This depends on the classes implemented, i.e. the complexity for adding an element to an array list would be O(1), whereas the complexity for searching for an element in a tree set would be O(log n).

What are the different types of lists?

An array list is a dynamic array, whereas a linked list is a doubly-linked list with pointers to the next nodes.

What's the difference between a hash set and tree set?

Both of these implement the set interface, but a hash set uses a hash table. In contrast, a tree set uses a binary search tree as its structure.

To top