Pages

Friday, December 4, 2020

Java 8 Stream forEach With Index

1. Overview

In this tutorial, We'll learn how to print the index when using java 8 forEach with streams.

In real-time when working with list.stream().forEach() method, it does not allow to use the index variable which is declared outside lambda expression.  If we declare the variable inside lambda then it will be reset to the initial value again. So, it is not possible and there are limitations while accessing the variables from inside lambda expressions

Let us explore the ways to get the indices when using forEach method on streams.

First, We'll show the example using Arrays and next on the List of String objects. Getting the index value or number can be addressed with IntStream.range() method.

Java 8 Stream forEach With Index




2. Java forEach Array With Index


Follow the below steps to get the values with indices from Array of Strings.

Steps:

Step 1: Create a string array using {} with values inside.
Step 2: Get the length of the array and store it inside a variable named length which is int type.
Step 3: Use IntStream.range() method with start index as 0 and end index as length of array. Next, the Call forEach() method and gets the index value from the int stream. This index value starts from 0 value so we can get the value from the string array using the index as fruites[0].
Step 4: Print the value along with the index.

package com.javaprogramto.java8.foreach.index;

import java.util.stream.IntStream;

/**
 * Example program to run the forEach() loop with index in java 8 with an array of Strings.
 * 
 * @author JavaProgramTo.com
 *
 */

public class ForEachIndexArraysExample {

	public static void main(String[] args) {

		// Create an Array with Strings.
		String[] fruites = { "Mango", "Apple", "Orange", "Kiwi", "Avocado" };

		// getting length of an array.
		int length = fruites.length;

		// running foreach loop with index using IntStream.range() method with start and end index.
		IntStream.range(0, length)
				.forEach(index -> System.out.println("Value at Index : " + (index + 1) + " is " + fruites[index]));
	}
}
Output:
Value at Index : 1 is Mango
Value at Index : 2 is Apple
Value at Index : 3 is Orange
Value at Index : 4 is Kiwi
Value at Index : 5 is Avocado

We can observe the output that is having the index values.

And also we can perform all normal stream operations such as map(), filter() on the IntStream.

Look at the below line of code that gets only if the fruit name is having the only the letter "a" in it. But, it holds the actual index from the original array.
// with filter() method.
IntStream.range(0, length).filter(index -> fruites[index].contains("a"))
		.forEach(index -> System.out.println("Value at Index : " + (index + 1) + " is " + fruites[index]));


Output:
Value at Index : 1 is Mango
Value at Index : 3 is Orange
Value at Index : 5 is Avocado

3. Java forEach List With Index


Iterating the list using forEach with indices can be done in two ways. 

The first option is directly use the IntStream.range() method to get the index and call forEach() is get the values from list using index as list.get(index). This approach is similar to the foreach array with an index.

The second approach is converting List to Map in such a way that the key should hold the index, the value will be the actual value from list. Finally, print the map using forEach(k, v).

3.1 Using IntStream.range()


Running forEach loop on top of IntStream.range() + filter() methods.

package com.javaprogramto.java8.foreach.index;

import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;

/**
 * Example program to run the forEach() loop with index in java 8 with an List
 * of Strings.
 * 
 * @author JavaProgramTo.com
 *
 */

public class ForEachIndexListExample {

	public static void main(String[] args) {

		// Create a List with Strings.
		List<String> players = Arrays.asList("Warner", "Ponting", "Akthar", "Sachin", "Gary Christian");

		// getting length of an List.
		int length = players.size();

		// running forEach loop with index using IntStream.range() method with start 0 and
		// end index as length
		IntStream.range(0, length).filter(index -> players.get(index).contains("a"))
				.forEach(index -> System.out.println("Value at Index : " + (index + 1) + " is " + players.get(index)));
	}
}

Output:
Value at Index : 1 is Warner
Value at Index : 3 is Akthar
Value at Index : 4 is Sachin
Value at Index : 5 is Gary Christian

3.2 Using Stream.collect() + Map + forEach()


Follow the below steps to get the list with the index. 

Step 1: Create a List with a string of values.
Step 2: Convert the list to map using the collect() method with Supplier and BiConsumer lambdas.
Step 3: Add the key as map.size() and value will be from the stream.

Collect() Method Syntax:

collect() is a terminal operation.
<R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner);
Example
package com.javaprogramto.java8.foreach.index;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

/**
 * Example program to run the forEach() loop with index in java 8 with an List
 * of Strings.
 * 
 * @author JavaProgramTo.com
 *
 */

public class ForEachIndexListMapExample {

	public static void main(String[] args) {

		// Create a List with Strings.
		List<String> players = Arrays.asList("Warner", "Ponting", "Akthar", "Sachin", "Gary Christian");


        HashMap<Integer, String> collect = players
                .stream()
                .collect(HashMap<Integer, String>::new,
                        (map, streamValue) -> map.put(map.size(), streamValue),
                        (map, map2) -> {
                        });

        collect.forEach((k, v) -> System.out.println(k + ":" + v));
	}
}

Output:
0:Warner
1:Ponting
2:Akthar
3:Sachin
4:Gary Christian

Here when the collect() is invoked, the first value is added to map before that map size will be 0. So, the index for the first value will be 0. 
Next, when the second value is added to the map, the index will be 1 because the map has already one element from the previous step. So the index is added as 1. 
These steps will be repeated till the last value in the stream. So for the last element index will be list.size()-1.

4. Conclusion


In this article, we've seen how to get the indices in java 8 Stream forEach() method using IntStream.range() and Stream.collect().forEach() method. This index will be considered as the position of the value in the collection or ArrayList.

Sometimes you may get out of bound error if you do not get the correct index.



No comments:

Post a Comment

Please do not add any spam links in the comments section.