Core Java

Add Elements to Java Collection

Looping through a List is a frequent task in Java, yet appending elements to it during iteration demands careful attention to prevent exceptions and maintain code accuracy. Let us delve into understanding different ways to add elements to a collection in Java.

1. Introduction

In Java, an iterator is an interface provided by the Collection framework. It allows traversing through a collection of objects one by one. Iterators are commonly used to iterate over collections like Lists, Sets, and Maps. Different types of iterators are available in Java, each catering to specific needs and collection types. Let’s explore the main types:

  • Iterator: The Iterator interface is the most common type of iterator in Java. It provides a uniform way to iterate over collections such as Lists, Sets, and Maps. It offers methods like hasNext() to check for the next element and next() to retrieve it.
  • ListIterator: ListIterator is a subinterface of Iterator specifically designed for iterating over lists, such as ArrayList and LinkedList. It extends the capabilities of the Iterator interface by providing methods for bidirectional traversal, element insertion, replacement, and backward iteration.
  • Spliterator: The Spliterator interface was introduced in Java 8 as part of the Stream API. It is designed for parallel traversal and partitioning of elements in collections. Spliterator provides methods like tryAdvance() and forEachRemaining() for efficient parallel processing of elements.
  • Enumeration: Enumeration is the oldest iterator interface in Java, introduced in the early versions of the Java collections framework. Although less commonly used now, it is still supported in legacy APIs like Vector and Hashtable. Enumeration provides methods like hasMoreElements() and nextElement() for iterating over elements.

1.1 Using Iterator

To use an iterator, first, obtain an iterator object from the collection using the iterator() method. Then, use the hasNext() method to check if there are more elements in the collection, and the next() method to retrieve the next element.

1.2 Advantages of Iterator

  • Iterator provides a uniform way of traversing various types of collections.
  • It allows removing elements from the collection during iteration using the remove() method.
  • It prevents concurrent modification exceptions when modifying the collection while iterating.

2. Exploring ListIterator in Java

The ListIterator interface in Java extends the capabilities of the Iterator interface to allow bidirectional traversal of lists. It enables operations such as adding, removing, and replacing elements while iterating over a list.

2.1 Example Usage

Let’s consider a scenario where we have a list of strings and we want to iterate over it using ListIterator to perform various operations:

import java.util.ArrayList;
import java.util.ListIterator;

public class ListIteratorExample {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("Apple");
        list.add("Banana");
        list.add("Orange");

        // Getting ListIterator
        ListIterator<String> iterator = list.listIterator();

        // Forward iteration
        System.out.println("Forward iteration:");
        while (iterator.hasNext()) {
            String element = iterator.next();
            System.out.println(element);
        }

        // Backward iteration
        System.out.println("\nBackward iteration:");
        while (iterator.hasPrevious()) {
            String element = iterator.previous();
            System.out.println(element);
        }

        // Adding an element
        iterator.add("Grapes");
        System.out.println("\nList after adding 'Grapes': " + list);

        // Replacing an element
        iterator.next(); // Move to the next element
        iterator.set("Mango");
        System.out.println("List after replacing 'Banana' with 'Mango': " + list);

        // Removing an element
        iterator.previous(); // Move to the previous element
        iterator.remove();
        System.out.println("List after removing 'Mango': " + list);
    }
}

2.2 Output

This shows how we move through the list both forward and backward. We add “Grapes” to the list, change “Banana” to “Mango”, and then remove “Mango” from the list.

  • Forward Iteration: We go through the list step by step from the start to the end, printing each fruit along the way: “Apple”, “Banana”, and “Orange”.
  • Backward Iteration: After going forward, we go back through the list from the end to the start, printing the fruits in reverse order: “Orange”, “Banana”, and “Apple”.
  • Adding an Element: We include “Grapes” in the list, making it longer.
  • Replacing an Element: We swap “Banana” with “Mango” in the list.
  • Removing an Element: We take out “Mango” from the list, making it shorter.
Forward iteration:
Apple
Banana
Orange

Backward iteration:
Orange
Banana
Apple

List after adding 'Grapes': [Apple, Banana, Grapes, Orange]
List after replacing 'Banana' with 'Mango': [Apple, Mango, Grapes, Orange]
List after removing 'Mango': [Apple, Grapes, Orange]

3. Enhanced for Loop With a Copy in Java

In Java, when iterating over a collection and adding elements to it, it’s essential to use a copy of the collection to avoid concurrent modification exceptions. The Enhanced for Loop With a Copy technique provides a simple solution for this scenario by iterating over a copy of the collection.

3.1 Example Usage

Let’s consider a scenario where we have an ArrayList of integers, and we want to double each element in the list while adding new elements:

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

public class EnhancedForLoopWithCopyExample {
    public static void main(String[] args) {
        // Original ArrayList
        List<Integer> originalList = new ArrayList<>();
        originalList.add(1);
        originalList.add(2);
        originalList.add(3);

        // Create a copy of the original list
        List<Integer> copyList = new ArrayList<>(originalList);

        // Iterate over the copy list and double each element, adding new elements
        for (int num : copyList) {
            originalList.add(num * 2);
        }

        // Output the modified list
        System.out.println("Modified list:");
        for (int num : originalList) {
            System.out.println(num);
        }
    }
}

In this example, we start with an ArrayList called originalList containing integers 1, 2, and 3. We then create a copy of this list called copyList using the ArrayList constructor. Next, we iterate over copyList using the enhanced for loop and double each element. While doing so, we add the doubled elements to the original list. Finally, we output the modified list, which now includes the original elements and their doubled counterparts.

3.2 Output

The output of the provided Java code will be:

Squared elements:
Modified list:
1
2
3
2
4
6

4. Java 8 Stream Approach

In Java 8 and later versions, the Stream API provides a powerful way to perform aggregate operations on collections of objects. This includes adding elements to a collection during iteration, thanks to the flexibility of the Stream approach.

4.1 Example Usage

Let’s consider a scenario where we have an ArrayList of integers, and we want to add the squared values of each element to another ArrayList using the Stream approach:

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

public class StreamApproachExample {
    public static void main(String[] args) {
        // Original ArrayList
        List originalList = new ArrayList();
        originalList.add(1);
        originalList.add(2);
        originalList.add(3);

        // Use Stream to add squared elements to another ArrayList
        List squaredList = new ArrayList();
        originalList.stream()
                    .map(num -> num * num)
                    .forEach(squaredList::add);

        // Output the modified list
        System.out.println("Modified list:");
        for (int num : squaredList) {
            System.out.println(num);
        }
    }
}

In this example, we start with an ArrayList called originalList containing integers 1, 2, and 3. We then use the Stream API to transform each element of the original list by squaring it. The map() operation applies the squaring function to each element, and the forEach() terminal operation adds the squared elements to the squaredList. Finally, we output the modified list, which now contains the squared values of the original elements.

4.2 Output

The output of the provided Java code will be:

Modified list:
1
4
9

5. Conclusion

When it comes to adding elements to a collection during iteration in Java, various approaches offer different advantages and suitability for different scenarios.

The ListIterator class provides bidirectional traversal of lists, allowing for efficient manipulation of elements while iterating. By using methods like add(), set(), and remove(), elements can be added to a collection during iteration with accuracy and flexibility.

The Enhanced for Loop With a Copy technique involves iterating over a copy of the collection to avoid concurrent modification exceptions. By creating a separate copy, modifications can be safely made to the original collection without affecting the iteration process, ensuring robustness and reliability in dynamic collection manipulation.

The Java 8 Stream Approach offers a functional-style way to process collections, including adding elements during iteration. With operations like map() and forEach(), elements can be transformed and added to a collection seamlessly, providing a concise and expressive solution for data processing tasks.

In conclusion, each of these approaches offers its own strengths and benefits, catering to different use cases and preferences. Whether it’s the flexibility of ListIterator, the safety of Enhanced for Loop With a Copy, or the elegance of Java 8 Stream Approach, Java provides a rich set of tools for efficiently adding elements to collections during iteration.

Yatin Batra

An experience full-stack engineer well versed with Core Java, Spring/Springboot, MVC, Security, AOP, Frontend (Angular & React), and cloud technologies (such as AWS, GCP, Jenkins, Docker, K8).
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button