Addition of Predicate-based findIndex and findLastIndex methods to java.util.List
Remi Forax
forax at univ-mlv.fr
Fri Apr 19 17:47:21 UTC 2024
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.olexandr at gmail.com>
> To: "core-libs-dev" <core-libs-dev at 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20240419/58dfc53a/attachment-0001.htm>
More information about the core-libs-dev
mailing list