May 10, 2021 Java
In the Java Collections Framework, different types of collections use different types of data structures to store their elements in different ways.
Some collections sort their elements, some don't. The collection framework provides the following methods for traversing the collection:
The collection provides an iterator to traverse all its elements.
The iterator can do three actions on the collection:
The iterator in
Iterator< E>
We can use the iterator() method in the College interface to get the iterator of the collection.
The following code creates a list of strings and gets the iterator of the list:
import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class Main { public static void main(String[] args) { // Create a list of strings List<String> names = new ArrayList<>(); // Get an iterator for the list Iterator<String> nameIterator = names.iterator(); } }
The iterator-e-gt; interface contains the following methods:
boolean hasNext() E next() default void remove() default void forEachRemaining(Consumer<? super E> action)
If there are more elements in the collection to
hasNext()
method returns true.
Otherwise, it returns false.
next()
method returns the next element in the collection. W
e should call the
hasNext()
method.
next()
If not,
next()
method throws the NoSuchElementException exception.
Typically,
hasNext()
next()
methods are used together in a loop.
The following code prints all the elements of the list using the iterator:
import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class Main { public static void main(String[] args) { // Create a list of strings List<String> names = new ArrayList<>(); names.add("A"); names.add("B"); names.add("C"); // Get an iterator for the list Iterator<String> nameIterator = names.iterator(); // Iterate over all elements in the list while (nameIterator.hasNext()) { // Get the next element from the list String name = nameIterator.next(); System.out.println(name); } } }
The code above produces the following results.
remove()
method removes the last element returned by the
next()
method.
The next() method can only be called once per call to
remove()
method.
If the
next()
called multiple times for each next() method or before the first call to
remove()
it throws an
IllegalStateException
exception.
Support
remove()
method is optional.
remove()
method may throw
UnsupportedOperationException
exception.
The following code uses an iterator to traverse all elements of the list and removes the element using the remove() method.
import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class Main { public static void main(String[] args) { // Create a list of strings List<String> names = new ArrayList<>(); names.add("A"); names.add("B"); names.add("C"); Iterator<String> nameIterator = names.iterator(); // Iterate over all elements in the list while (nameIterator.hasNext()) { // Get the next element from the list String name = nameIterator.next(); System.out.println(name); nameIterator.remove(); } System.out.println(names); } }
The code above produces the following results.
The forEachRemaining() method performs operations on each element in the collection that has not yet been accessed by the iterator.
Action is specified
Consumer
The following code shows how to print all the elements of the list.
import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class Main { public static void main(String[] args) { // Create a list of strings List<String> names = new ArrayList<>(); names.add("A"); names.add("B"); names.add("C"); Iterator<String> nameIterator = names.iterator(); nameIterator.forEachRemaining(System.out::println); } }
The code above produces the following results.
The iterator is a one-time object. We can't reset the iterator, it can't be reused.
To traverse elements of the same collection again, create a new Iterator by calling the iterator() method of the collection.
We can use the for-each loop to traverse the elements of the collection.
We can use the for-each loop to traverse any collection of implementation classes implementing the Iterable interface.
The general syntax of the for-each loop is as follows:
Collection<T> yourCollection = ;
for(T element : yourCollection) {
}
Behind the scenes, the for-each loop gets the iterator and calls the hasNext() and next() methods.
import java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) { // Create a list of strings List<String> names = new ArrayList<>(); names.add("A"); names.add("B"); names.add("C"); for (String name : names) { System.out.println(name); } } }
The code above produces the following results.
The for-each loop has several limitations.
We cannot use the for-each loop to remove elements from the collection.
The following code throws the ConcurrentModificationException exception:
List<String> names = get a list;
for(String name : names) {
names.remove(name);// Throws a ConcurrentModificationException
}
For the for-each loop, there is no way to start in the middle of the collection.
The for-each loop does not provide a way to access previously accessed elements.
The Iterable interface
forEach(Consumer action)
The method traverses all elements and applies the action.
forEach()
method is available in all collection types inherited from the
Collection
interface.
import java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) { // Create a list of strings List<String> names = new ArrayList<>(); names.add("A"); names.add("B"); names.add("C"); names.forEach(System.out::println); } }
The code above produces the following results.