Search code examples
javajava-8java-stream

Is There Some Stream-Only Way To Determine The Index Of The Max Stream Element?


I have a Stream<Set<Integer>> intSetStream.

I can do this on it...

Set<Integer> theSetWithTheMax = intSetStream.max( (x,y)->{ return Integer.compare( x.size(), y.size() ); } ).get( );

...and I get a hold of the Set<Integer> that has the highest number of Integer elements in it.

That's great. But what I really need to know is, is it the 1st Set in that Stream that's the max? Or is it the 10th Set in the Stream? Or the ith Set? Which one of them has the most elements in it?

So my question is: Is there some way — using the Stream API — that I can determine "It was the ith Set in the Stream of Sets that returned the largest value of them all, for the Set.size( ) call"?

The best solution I can think of, is to iterate over the Stream<Set<Integer>> (using intSetStream.iterator()) and do a hand-rolled max( ) calculation. But I'm hoping to learn a more Stream-y way to go about it; if there is such a thing.


Solution

  • One way to do it is to firstly map Stream<Set<Integer>> to a Collection<Integer> where each element is the size of each Set<Integer> and then you can extract what is the largest number of elements given Stream<Set<Integer>> and then get the "index" of this set by finding an index of the largest number in the collection of sizes.

    Consider following example:

    import java.util.Arrays;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Set;
    import java.util.stream.Collectors;
    import java.util.stream.Stream;
    
    public class IntSetStreamExample {
    
        public static void main(String[] args) {
    
            final Stream<Set<Integer>> stream = Stream.of(
                    new HashSet<>(Arrays.asList(1,2,3)),
                    new HashSet<>(Arrays.asList(1,2)),
                    new HashSet<>(Arrays.asList(1,2,3,4,5)),
                    new HashSet<>(Arrays.asList(0)),
                    new HashSet<>(Arrays.asList(0,1,2,3,4,5)),
                    new HashSet<>()
            );
    
            final List<Integer> result = stream.map(Set::size).collect(Collectors.toList());
    
            System.out.println("List of number of elements in Stream<Set<Integer>>: " + result);
    
            final int max = Collections.max(result);
    
            System.out.println("Largest set contains " + max + " elements");
    
            final int index = result.indexOf(max);
    
            System.out.println("Index of the largest set: " + index);
        }
    }
    

    The exemplary output may look like this:

    List of number of elements in Stream<Set<Integer>>: [3, 2, 5, 1, 6, 0]
    Largest set contains 6 elements
    Index of the largest set: 4