Java iterator foreachremaining example

Introduction to forEachRemaining() in Java’s Iterator

Iterator is an interface available in the Collections framework in the java.util package. It is used to iterate a collection of objects. This interface has four methods, as shown in the image below.

Before Java 8, the forEachRemaining() method did not exist.

Iteration before Java 8

Below is a simple program that shows how you would iterate a list using an iterator before Java 8.

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class IteratorDemo
public static void main(String args[])
List fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Grapes");
fruits.add("Orange");
Iterator iterator = fruits.iterator();
while (iterator.hasNext())
System.out.println(iterator.next());
>
>
>

As you can see, the above example requires a while loop in order to iterate through the input list via an Iterator . To avoid this, the forEachRemaining() method was introduced in Java 8. This method takes in a Consumer instance as a parameter.

The Consumer interface lesson takes in a parameter and does not return anything. This is what we require for our iterator.

Iteration using forEachRemaining()

Below is the same example shown above, but this time, we are using the forEachRemaining() method.

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class IteratorDemo
public static void main(String args[])
List fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Grapes");
fruits.add("Orange");
Iterator iterator = fruits.iterator();
iterator.forEachRemaining((fruit) -> System.out.println(fruit));
>
>

Therefore, the main purpose of introducing the forEachRemaining() method was to make the iteration code more concise and readable.

Data Analysis & Processing with Pandas

Источник

Java Iterator

The Java Iterator interface represents an object capable of iterating through a collection of Java objects, one object at a time. The Iterator interface is one of the oldest mechanisms in Java for iterating collections of objects (although not the oldest — Enumerator predated Iterator ).

To use a Java Iterator you will have to obtain an Iterator instance from the collection of objects you want to iterate over. The obtained Iterator keeps track of the elements in the underlying collection to make sure you iterate through all of them. If you modify the underlying collection while iterating through an Iterator pointing to that collection, the Iterator will typically detect it, and throw an exception the next time you try to obtain the next element from the Iterator. More about that later.

Java Iterator Tutorial Video

If you prefer video, I have a video version of this Java Iterator tutorial: Java Iterator Tutorial

Java Iterator video

Java Iterator Core Methods

The Java Iterator interface is reasonably simple. The core methods of the Iterator interface are:

Method Description
hasNext() Returns true if the Iterator has more elements, and false if not.
next() Return the next element from the Iterator
remove() Removes the latest element returned from next() from the Collection the Iterator is iterating over.
forEachRemaining() Iterates over all remaining elements in the Iterator and calls a Java Lambda Expression passing each remaining element as parameter to the lambda expression.

Each of these methods will be covered in the following sections.

Obtaining an Iterator

Most often that is how you will interact with an Iterator by obtaining it from some Java object that contains multiple nested objects. The standard Java collection interface Collection contains a method called iterator() . By calling iterator() you can obtain an iterator from the given Collection .

You can also obtain an Iterator from many of the Java Collection data structures, e.g. a List , Set , Map , Queue , Deque or Map .

Here are a few examples of obtaining a Java Iterator from various Java collection types:

List list = new ArrayList<>(); list.add("one"); list.add("two"); list.add("three"); Iterator iterator = list.iterator(); Set set = new HashSet<>(); set.add("one"); set.add("two"); set.add("three"); Iterator iterator2 = set.iterator();

Iterating an Iterator

You iterate the objects in an Iterator using a while loop. Here is an example of iterating the elements of a Java Iterator using a while loop:

Iterator iterator = list.iterator(); while(iterator.hasNext())

There are two methods to pay attention to in the above Java example. The first method is the Iterator hasNext() method which returns true if the Iterator contains more elements. In other words, if the Iterator has not yet iterated over all of the elements in the collection the Iterator was obtained from — the hasNext() method will return true . If the Iterator has iterated over all elements in the underlying collection — the hasNext() method returns false .

The second method to pay attention to is the next() method. The next() method returns the next element of the collection the Iterator is iterating over.

Iteration Order

The order in which the elements contained in a Java Iterator are traversed depends on the object that supplies the Iterator . For instance, an iterator obtained from a List will iterate through the elements of that List in the same order the elements are stored internally in the List . An Iterator obtained from a Set , on the other hand, does not make any guarantees about the exact sequence the elements in the Set are iterated in.

Java List Iterator

Here is an example of obtaining a Java Set Iterator from a List instance:

List list = new ArrayList(); list.add("123"); list.add("456"); list.add("789"); Iterator iterator = list.iterator();

Java Set Iterator

Here is an example of obtaining a Java Set Iterator from a Set instance:

Set set = new HashSet(); set.add("123"); set.add("456"); set.add("789"); Iterator iterator = set.iterator();

Modification During Iteration

Some collections do not allow you to modify the collection while you are iterating it via an Iterator . In that case you will get a ConcurrentModificationException the next time you call the Iterator next() method. The following example results in a ConcurrentModificationException when executed:

List list = new ArrayList<>(); list.add("123"); list.add("456"); list.add("789"); Iterator iterator = list.iterator(); while(iterator.hasNext()) < String value = iterator.next(); if(value.equals("456"))< list.add("999"); >>

The ConcurrentModificationException is thrown because the Iterator gets out of sync with the collection, if you modify the collection while iterating it via the Iterator .

Remove Elements During Iteration

The Java Iterator interface has a remove() method which lets you remove the element just returned by next() from the underlying collection. Calling remove() does not cause a ConcurrentModificationException to be thrown. Here is an example of removing an element from a collection during iteration of its Iterator :

List list = new ArrayList<>(); list.add("123"); list.add("456"); list.add("789"); Iterator iterator = list.iterator(); while(iterator.hasNext()) < String value = iterator.next(); if(value.equals("456"))< iterator.remove(); >>

forEachRemaining()

The Java Iterator forEachRemaining() method can iterate over all of the elements remaining in the Iterator internally, and for each element call a Java Lambda Expression passed as parameter to forEachRemaining() . Here is an example of using the Java Iterator forEachRemaining() method:

List list = new ArrayList<>(); list.add("Jane"); list.add("Heidi"); list.add("Hannah"); Iterator iterator = list.iterator(); iterator.forEachRemaining((element) -> < System.out.println(element); >);

ListIterator

Java also contains an interface called ListIterator which extends the Iterator interface. The Java ListIterator interface which represents a bi-directional iterator — meaning an iterator where you can navigate the elements both forward and backwards. I won’t cover the ListIterator interface in detail here, but I will show you a quick example of how it can be used:

List list = new ArrayList<>(); list.add(«Jane»); list.add(«Heidi»); list.add(«Hannah»); ListIterator listIterator = list.listIterator(); while(listIterator.hasNext()) < System.out.println(listIterator.next()); >while(listIterator.hasPrevious())

As you can see, the example first iterates the ListIterator forward through all the elements, and then backwards again through all the elements back to the first element.

Implement the Iterator Interface in Your Own Class

If you have a special, custom made type of collection, you can implement the Java Iterator interface yourself to create an Iterator that can iterate through the elements of your custom collection. In this section I will show you a super simple custom implementation of the Java Iterator interface that will give you an impression of how implementing the Iterator interface yourself looks.

The collection I will implement an Iterator for is a standard Java List . It won’t be a fully perfect implementation as it will not be able to detect changes to the contents of the List during iteration, but it is enough to give you an idea about how an Iterator implementation could look. Here it is:

import java.util.Iterator; import java.util.List; public class ListIterator implements Iterator  < private Listsource = null; private int index = 0; public ListIterator(List source) < this.source = source; >@Override public boolean hasNext() < return this.index < this.source.size(); >@Override public T next() < return this.source.get(this.index++); >>

Here is an example of how it looks during iteration of the above ListIterator:

import java.util.ArrayList; import java.util.List; public class ListIteratorExample < public static void main(String[] args) < Listlist = new ArrayList(); list.add("one"); list.add("two"); list.add("three"); ListIterator iterator = new ListIterator<>(list); while(iterator.hasNext()) < System.out.println( iterator.next() ); >> >

Источник

LearnJava

Java 8 Iterator forEachRemaining method with code samples

Java 8 has added a method called forEachRemaning to the Iterator interface. This helps in using an Iterator to internally iterate over a Collection, without an explicit loop. In this article, I will be covering this method with a code sample.

Pre Java 8 code

Before Java 8, you had to write code similar to the following in order to use an Iterator:

public class ForEachRemainingDemo < public static void main(String[] args) < Listinput = Arrays.asList(5, 3, 11, 15, 9, 2, 5, 11); Iterator itr = input.iterator(); while(itr.hasNext()) System.out.println(itr.next()); > >

So in this code, you need to use a while loop in order to use the iterator to iterate through the input list.

Using Java 8 forEachRemaining

Java 8 added the forEachRemanining method to the Iterator interface. So using this method, the above code can be re-written as follows:

public class ForEachRemainingDemo < public static void main(String[] args) < Listinput = Arrays.asList(5, 3, 11, 15, 9, 2, 5, 11); Iterator itr = input.iterator(); itr.forEachRemaining(num -> System.out.println(num)); > >

forEachRemaining Explained

So basically, when you use the forEachRemaining method, you no longer require a while loop in order to iterate through the input list via an Iterator. The forEachRemaining method accepts as a parameter a Consumer instance. The above code implements this via a lambda expression, that simply prints the number. The forEachRemaining method does not provide any other benefit other than eliminating the need to write a while loop.

Conclusion

The forEachRemaining is a new method in the Iterator interface and helps to iterate through a Collection without an explicit loop when an Iterator is used.

If you’d like to watch a detailed video tutorial of this topic or other related topics, do check out my new course Learn Java 8 New Features

If you like this post, please do let me know via the comments box below. You can also connect with me via my Facebook Page or subscribe to my Youtube channel!

Источник

Читайте также:  text-align
Оцените статью