Predicate based method of Java 8 stream indexof

See English answers > stream way to get index of first element matching Boolean

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

But it didn't help Of course, I can write like this:

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

But this will a) iterate the list twice (in the worst case, the element will be the last) and b) fail if there is no element matching predicate (I prefer - 1 Index)

I have written a utility method for this function:

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;
}

However, since this seems to be a very simple algorithm, I expected it somewhere in the Java 8 stream API I just miss it, or does it really have no such function? (additional question: if there is no such method, is there a good reason? Is it possible that using indexes in functional programming is an anti pattern?)

Solution

Your loop is good, 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 similar stream

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 if the list is large instead of random access, it will become quiet and inefficient I'll stay in the loop

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>