top

Search

Java Tutorial

.

UpGrad

Java Tutorial

Collections in Java

Introduction 

Collections in Java are objects They serve as a unified entity to hold and manage a group of objects. These are referred to as its elements. It provides a standardized approach for handling objects within a class. It does so by treating them as a cohesive unit.

Overview

This tutorial elaborates on the various aspects of collections in Java, including answers to standard questions such as “What is a collection in Java?”, “What is a framework in Java?” and “Hierarchy of collection.” 

Read on to learn more.

What Is Collection in Java?

In real-life scenarios, collections in Java can be compared to various everyday situations to understand their functionality:

  • Linked List: A linked list can be likened to your browsing history. Here, each visited webpage is linked to the next one you visit. Elements can be easily added or removed from a linked list. This is similar to adding or removing pages from your browsing history.

  • Stacks: Imagine a stack of plates or trays in a cafeteria. When you need to take a plate, you pick one from the top of the stack. This is the most recently placed plate. Likewise, the last element added in a stack collection is the first to be accessed or removed.

  • Queue: A queue in Java is similar to real-life queues. The first person to enter the queue is also the first to leave it. Likewise, elements in a queue collection are processed according to their order. Essentially, it adheres to the principle of “FIFO” (first in, first out). 

What Is a Framework in Java?

A framework in Java is a reusable and pre-designed structure. This provides a foundation for developing applications. It offers pre-defined functions, classes, and libraries. These simplify and accelerate the development process.

What Is a Collection Framework?

The collections framework in Java is a comprehensive architecture. It is designed to simplify the representation and manipulation of collections. It consists of a hierarchy of interfaces and classes. This is within the java.util package. This makes it a widely used and powerful tool in Java programming.

The collections framework streamlined the handling of collections in Java. This is primarily due to its common interface and interconnection between various collection types. It offers a range of interfaces, classes, and algorithms. They facilitate efficient storage and manipulation of groups of objects. As a result, it enhances the productivity and effectiveness of Java developers.

Hierarchy of Collection Framework

The collections framework in Java is structured in a hierarchy. It encompasses classes and interfaces found in the java.util package.

Let's clarify some key terms so that we can understand the hierarchy better:

  • Class: A class represents a collection of similar objects. It serves as an implementation of a collection interface.

  • Interface: An interface is an abstract data type. It resides at the topmost position in the framework hierarchy. It defines a group of related methods with empty bodies, providing functionality while hiding implementation details through abstraction.

  • Extends: "extends" is a keyword utilized to establish inheritance between classes or interfaces. In Java, inheritance allows the creation of new classes based on existing ones. This is done by inheriting their properties and behaviors.

  • Implements: "implements" is also a keyword used to establish inheritance. However, this is specifically between a class and an interface. When a class implements an interface, it adheres to the defined contract of the interface. It is done by implementing its methods.

Methods of Collection Interface

Iterator Interface

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class upGradTutorials {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Java");
        list.add("Python");
      
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            String element = iterator.next();
            System.out.println(element);
            iterator.remove();
        }
    }
}

Syntax:

  • boolean hasNext(): Returns true if more elements are in the collection.

  • E next(): Returns the next element in the collection.

  • void remove(): Removes the last element returned by next() from the collection.

Iterable Interface

import java.util.ArrayList;
import java.util.List;

public class upGradTutorials {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        
        for (Integer element : list) {
            System.out.println(element);
        }
    }
}

Syntax:

  • Iterator<E> iterator(): Returns an iterator over the elements in the collection.

Collection Interface

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class upGradTutorials {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Java");
        list.add("Python");
        list.remove("Java");
        System.out.println(list.contains("Python"));
    }
}

Syntax:

  • boolean add(E element): Adds an element to the collection.

  • boolean remove(Object element): Removes the specified element from the collection.

  • boolean contains(Object element): Returns true if the collection contains the specified element.

List Interface (extends Collection)

import java.util.ArrayList;
import java.util.List;

public class upGradTutorials {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Apple");
        list.add(0, "Banana");
        System.out.println(list.get(1));
        System.out.println(list.size());
    }
}

Syntax:

  • void add(int index, E element): Inserts an element at the specified index.

  • E get(int index): Returns the element at the specified index.

  • int size(): Returns the number of elements in the list.

ArrayList (implements List)

import java.util.ArrayList;
import java.util.List;

public class upGradTutorials {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Apple");
        list.add("Banana");
        list.add("Orange");
        System.out.println(list);
    }
}

Syntax:

  • ArrayList: Resizable array-based implementation of the List interface.

LinkedList (implements List)

import java.util.LinkedList;
import java.util.List;

public class upGradTutorials {
    public static void main(String[] args) {
        List<String> list = new LinkedList<>();
        list.add("Apple");
        list.add("Banana");
        list.add("Orange");
        System.out.println(list);
    }
}

Syntax:

  • LinkedList: Doubly-linked list-based implementation of the List interface.

Vector (implements List)

import java.util.List;
import java.util.Vector;

public class upGradTutorials {
    public static void main(String[] args) {
        List<String> vector = new Vector<>();
        vector.add("Apple");
        vector.add("Banana");
        vector.add("Orange");
        System.out.println(vector);
    }
}

Syntax:

  • Vector: Legacy synchronized resizable array-based implementation of the List interface.

Stack (extends Vector)

import java.util.Stack;

public class upGradTutorials {
    public static void main(String[] args) {
        Stack<String> stack = new Stack<>();
        stack.push("Apple");
        stack.push("Banana");
        stack.push("Orange");
        System.out.println(stack.pop());
    }
}

Syntax:

  • Stack: Stack implementation based on the Vector class.

Queue Interface

import java.util.LinkedList;
import java.util.Queue;

public class upGradTutorials {
    public static void main(String[] args) {
        Queue<String> queue = new LinkedList<>();
        queue.offer("Apple");
        queue.offer("Banana");
        queue.offer("Orange");
        System.out.println(queue.poll());
        System.out.println(queue.peek());
    }
}

Syntax:

  • boolean offer(E element): Adds an element to the queue.

  • E poll(): Retrieves and removes the head of the queue.

  • E peek(): Retrieves, but does not remove, the head of the queue.

PriorityQueue

import java.util.PriorityQueue;
import java.util.Queue;

public class upGradTutorials {
    public static void main(String[] args) {
        Queue<Integer> queue = new PriorityQueue<>();
        queue.offer(5);
        queue.offer(2);
        queue.offer(8);
        System.out.println(queue.poll()); // Output: 2
        System.out.println(queue.peek()); // Output: 5
    }
}

Syntax:

  • offer(E e): Inserts the specified element into the priority queue.

  • poll(): Retrieves and removes the head of the queue.

  • peek(): Retrieves, but does not remove, the head of the queue.

Deque Interface

import java.util.ArrayDeque;
import java.util.Deque;

public class upGradTutorials {
    public static void main(String[] args) {
        Deque<String> deque = new ArrayDeque<>();
        deque.addFirst("Apple");
        deque.addLast("Banana");
        deque.addLast("Orange");
        System.out.println(deque.pollFirst());
        System.out.println(deque.peekLast());
    }
}

Syntax:

  • addFirst(E e): Inserts the specified element at the front of the deque.

  • addLast(E e): Inserts the specified element at the end of the deque.

  • pollFirst(): Retrieves and removes the first element of the deque.

  • pollLast(): Retrieves and removes the last element of the deque.

  • peekFirst(): Retrieves, but does not remove, the first element of the deque.

  • peekLast(): Retrieves, but does not remove, the last element of the deque.

ArrayDeque

import java.util.ArrayDeque;
import java.util.Deque;

public class upGradTutorials {
    public static void main(String[] args) {
        Deque<String> deque = new ArrayDeque<>();
        deque.add("Apple");
        deque.add("Banana");
        deque.add("Orange");
        System.out.println(deque);
    }
}

Syntax:

  • ArrayDeque: Inherits the methods from the Deque interface. Additionally, it provides methods to perform array-like operations, such as get(int index) and set(int index, E element).

Set Interface

import java.util.HashSet;
import java.util.Set;

public class upGradTutorials {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        set.add("Apple");
        set.add("Banana");
        set.add("Orange");
        System.out.println(set);
    }
}

Syntax:

  • Set: The Set interface does not introduce new methods but inherits from the Collection interface. It represents a collection that contains no duplicate elements.

HashSet

import java.util.HashSet;
import java.util.Set;

public class upGradTutorials {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        set.add("Apple");
        set.add("Banana");
        set.add("Orange");
        System.out.println(set);
    }
}

Syntax:

  • HashSet: Implements the Set interface. It uses a hash table for storing elements. This also provides constant-time performance for basic operations such as add(E e), contains(Object o), and remove(Object o).

LinkedHashSet

import java.util.LinkedHashSet;
import java.util.Set;

public class upGradTutorials {
    public static void main(String[] args) {
        Set<String> set = new LinkedHashSet<>();
        set.add("Apple");
        set.add("Banana");
        set.add("Orange");
        System.out.println(set);
    }
}

Syntax:

  • LinkedHashSet: Implements the Set interface. It maintains a linked list of the entries in the set in the order in which they were inserted. It also provides a predictable iteration order.

SortedSet Interface

import java.util.SortedSet;
import java.util.TreeSet;

public class upGradTutorials {
    public static void main(String[] args) {
        SortedSet<String> set = new TreeSet<>();
        set.add("Apple");
        set.add("Banana");
        set.add("Orange");
        System.out.println(set);
    }
}

Syntax:

  • SortedSet: Extends the Set interface. It introduces methods for retrieving elements based on their natural ordering or a custom comparator. Notable methods include first(), last(), headSet(E toElement), tailSet(E fromElement), etc.

TreeSet

import java.util.SortedSet;
import java.util.TreeSet;

public class upGradTutorials {
    public static void main(String[] args) {
        SortedSet<String> set = new TreeSet<>();
        set.add("Apple");
        set.add("Banana");
        set.add("Orange");
        System.out.println(set);
    }
}

Syntax:

  • TreeSet: Implements the SortedSet interface. It uses a tree structure (specifically, a Red-Black tree) to store elements. Provides sorted order for elements based on their natural ordering or a custom comparator.

Need for a Separate Collection Framework in Java

Before the collections framework was introduced, Java had individual classes. There were Vectors, Stacks, and Arrays. These were each with its own set of methods and functionality. This lack of standardization and uniformity made it challenging for developers to work with collections and limited code reusability.

The collections framework addresses these issues by providing a unified architecture with consistent interfaces and classes. It standardized how collections are represented, manipulated, and accessed, making it easier for developers to work with collections and enabling code reuse across different collection types. 

Additionally, the framework offers high-performance implementations of various data structures and algorithms, improving program speed and quality. Overall, the collections framework in Java greatly simplifies and enhances collection handling in programming.

Advantages of the Collection Framework

The collection framework in Java offers several advantages:

  • Consistent API: The framework provides a consistent set of interfaces, such as collection, set, list, and map, ensuring that classes implementing these interfaces have a common set of methods. This promotes code reusability and simplifies programming tasks.

  • Reduced programming effort: By leveraging the collection framework, programmers can focus on utilizing collections effectively in their programs without worrying about the underlying design. This supports the abstraction principle in object-oriented programming, enhancing code maintainability and readability.

  • Improved program speed and quality: The framework includes high-performance implementations of essential data structures and algorithms. Programmers can leverage these optimized implementations without devising their own, leading to faster and more efficient programs. This boosts performance and ensures reliable outcomes for various tasks and operations.

When To Use Which Collection Framework?

The choice of collection framework depends on the program's specific requirements.

  • Use ArrayList or LinkedList when you need a dynamic list supporting random access or efficient insertion/deletion.

  • Use HashSet or TreeSet when you require a collection with unique elements and no specific order or when you need elements sorted in a natural or custom order.

  • Use HashMap or TreeMap when you need key-value mappings, with HashMap offering faster access and TreeMap maintaining elements in sorted order.

  • Use Queue implementations like LinkedList or PriorityQueue when you require a FIFO or priority-based processing of elements.

Conclusion

Collections in Java give us a powerful set of tools to manage groups of objects. This helps us work with complex structures of data. If you aspire to be one, you could also enroll in a credible online software development course. Learning platforms such as upGrad have numerous software and web development courses to help you become a successful professional.

 FAQs

1. How is a map different from a collection?

A map is an interface that represents a mapping between keys and values. It is not considered a subtype of collection because it does not directly store objects. Map implementations, such as HashMap and TreeMap, store key-value pairs, allowing efficient lookup and retrieval based on keys.

2. Can I create my own custom collection classes in Java?

Yes, Java allows you to create your own custom collection classes by implementing the appropriate interfaces from the collection framework. This allows you to tailor collections to specific requirements and define custom behaviors and operations.

3. Is it possible to modify a collection while iterating over it?

In general, modifying a collection while iterating over it is not recommended using the enhanced for loop or an iterator. Doing so may result in a ConcurrentModificationException. Instead, use explicit methods like add, remove, or use the Iterator's remove method to modify the collection safely during iteration.

Leave a Reply

Your email address will not be published. Required fields are marked *