Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find all the indexes of an item within a list using stream API

I am trying sequential search using Java 8 streams and lambda expressions. Here is my code

List<Integer> list = Arrays.asList(10, 6, 16, 46, 5, 16, 7);
int search = 16;
list.stream().filter(p -> p == search).forEachOrdered(e -> System.out.println(list.indexOf(e)));
Output: 2
        2

I know list.indexOf(e) always prints the index of the first occurrence. How do I print all the indexes?

like image 697
mallikarjun Avatar asked Oct 03 '14 12:10

mallikarjun


People also ask

Can we get index in stream?

Overview Though we cannot access the index of the stream directly, we have a few workarounds to iterate the Java stream forEach with index.

How do you get the index of an item in a list in Java?

The indexOf(Object) method of the java. util. ArrayList class returns the index of the first occurrence of the specified element in this list, or -1 if this list does not contain the element. Using this method, you can find the index of a given element.

How do you find the index of an element in an ArrayList?

The index of a particular element in an ArrayList can be obtained by using the method java. util. ArrayList. indexOf().


2 Answers

For a start, using Lambdas is not the solution to all problems... but, even then, as a for loop, you would write it:

List<Integer> results = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
    if (search == list.get(i).intValue()) {
        // found value at index i
        results.add(i);
    }
}

Now, there's nothing particularly wrong with that, but note that the critical aspect here is the index, not the value. The index is the input, and the output of the 'loop'.

As a stream::

List<Integer> list = Arrays.asList(10, 6, 16, 46, 5, 16, 7);
int search = 16;
int[] indices = IntStream.range(0, list.size())
                .filter(i -> list.get(i) == search)
                .toArray();
System.out.printf("Found %d at indices %s%n", search, Arrays.toString(indices));

Produces output:

Found 16 at indices [2, 5]
like image 83
rolfl Avatar answered Oct 20 '22 02:10

rolfl


To find the indexes of every value in a List as a Map, we can use an IntStream of indexes with Collectors.groupingBy.

import java.util.stream.Collectors;
import java.util.stream.IntStream;
//...
final Map<Integer, List<Integer>> indexMap = IntStream.range(0, list.size()).boxed()
        .collect(Collectors.groupingBy(list::get));
//{16=[2, 5], 5=[4], 6=[1], 7=[6], 10=[0], 46=[3]}
//Map of item value to List of indices at which it occurs in the original List

Demo

Now, if you want to get the list of indices for search, you can do so as follows:

System.out.println(indexMap.get(search));
like image 1
Unmitigated Avatar answered Oct 20 '22 01:10

Unmitigated