Java 8 Stream indexOf method based on predicate [duplicate]

  • A+
Category:Languages

This question already has an answer here:

I just encountered the situation that I needed to know the index (position) of an element inside a list, but only had a predicate expression to identify the element. I had a look for a Stream function like

int index = list.stream().indexOf(e -> "TESTNAME".equals(e.getName())); 

but to no avail. Of course, I could write it like this:

int index = list.indexOf(list.stream().filter(e -> "TESTNAME".equals(e.getName()))     .findFirst().get()); 

But this would a) iterate over the list twice (in the worst case that the element would be the last one) and b) would fail if no element matches the predicate (where I would prefer a -1 index).

I wrote a utility method for this functionality:

public static <T> int indexOf(List<T> list, Predicate<? super T> predicate) {     int idx = 0;     for (Iterator<T> iter = list.iterator(); iter.hasNext(); idx++) {         if (predicate.test(iter.next())) {             return idx;         }     }      return -1; } 

But as this seems to be a really trivial algorithm, I would have expected it somewhere in the Java 8 Stream API. Did I just miss it, or is there really no such function? (Bonus question: In case there is no such method, is there a good reason? Is working with the index in functional programming perhaps an anti-pattern?)


Your loop is not bad, but you can simplify it:

public static <T> int indexOf(List<T> list, Predicate<? super T> predicate) {     for(ListIterator<T> iter = list.listIterator(); iter.hasNext(); )         if(predicate.test(iter.next())) return iter.previousIndex();     return -1; } 

You can use a stream like

public static <T> int indexOf(List<T> list, Predicate<? super T> predicate) {     return IntStream.range(0, list.size())         .filter(ix -> predicate.test(list.get(ix)))         .findFirst().orElse(-1); } 

but this will become quiet inefficient if the list is large and not random access. I’d stay with the loop.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: