Hello, for me, it seems what you want is Collector on Stream which is able to short-circuit, so you can write list.stream().collect(Collectors.findFirst(s -> s.contains("o"))) and in reverse list.reversed().stream().collect(Collectors.findFirst(s -> s.contains("o")))
Using a Stream here is more general and will work with other collections like a LinkedHashSet for example. Sadly, there is no way to define a short-circuiting collector :( You can have a short-circuiting Gatherer like this <T> Gatherer<T, ?, Integer> findIndex(Predicate<? super T> predicate) { return Gatherer.ofSequential( () -> new Object() { int index; }, Integrtor.ofGreedy((state, element, downstream) -> { var index = state.index++; if (predicate.test(element)) { return downstream.push(index); } return true; })); } and use it like this: list.stream().gather(findIndex(s -> s.contains("o"))).findFirst().orElse(-1); But it's more verbose. I wonder if at the same time that the Gatherer API is introduced, the Collector API should be enhanced to support short-circuiting collectors ? regards, Rémi > From: "ІП-24 Олександр Ротань" <rotan.olexa...@gmail.com> > To: "core-libs-dev" <core-libs-dev@openjdk.org> > Sent: Friday, April 19, 2024 5:59:39 PM > Subject: Addition of Predicate-based findIndex and findLastIndex methods to > java.util.List > Subject > Addition of Predicate-based findIndex and findLastIndex methods to > java.util.List > Motivation > The motivation behind this proposal is to enhance the functionality of the > List > interface by providing a more flexible way to find the index of an element. > Currently, the indexOf and lastIndexOf methods only accept an object as a > parameter. This limits the flexibility of these methods as they can only find > the index of exact object matches. > Here I want to propose methods that would accept a Predicate as a parameter, > allowing users to define a condition that the desired element must meet. This > would provide a more flexible and powerful way to find the index of an element > in a list. > The changes I am proposing are implemented in this PR: [ > https://github.com/openjdk/jdk/pull/18639 | > https://github.com/openjdk/jdk/pull/18639 ] . Here is a brief overview of the > changes made in this pull request: > Added the findIndex (Predicate<? super E> filter) method to the List > interface. > Added the findLastIndex (Predicate<? super E> filter) method to the List > interface. > Implemented these methods in all non-abstract classes that implement the List > interface, as well as List itself (default impl). > The changes have been thoroughly tested to ensure they work as expected and do > not introduce any regressions. The test cases cover a variety of scenarios to > ensure the robustness of the implementation. > For example, consider the following test case: > List<String> list = new ArrayList<>(); > list.add("Object one"); > list.add("NotObject two"); > list.add("NotObject three"); > int index1 = list.findIndex(s -> s.contains("ct t")); > System.out.println(index1); // Expected output: 1 > int index2 = list. findLastIndex(s -> s.startsWith("NotObject")); > System.out.println(index2); // Expected output: 2 > Currently, to achieve the same result, we would have to use a more verbose > approach: > int index1 = IntStream.range(0, list.size()) > .filter(i -> list.get(i).contains("ct t")) > .findFirst() > .orElse(-1); > System.out.println(index1); // Output: 1 > int index2 = IntStream.range(0, list.size()) > .filter(i -> list.get(i).startsWith("NotObject")) > .reduce((first, second) -> second) > .orElse(-1); > System.out.println(index2); // Output: 2 > Or other approaches that require additional instructions and, therefore, can`t > be used in all scopes (like passing argument to method). > I believe these additions would greatly enhance the functionality and > flexibility of the List interface, making it more powerful and user-friendly. > I > look forward to your feedback and am open to making any necessary changes > based > on your suggestions. > The main reason I am publishing this proposal in the mailing system is to > gather > feedback from the Java developers community, especially about possible caveats > related to backward compatibility of your projects. Would appreciate every > opinion! > Best regards