On Fri, 5 Apr 2024 00:31:22 GMT, Evemose <d...@openjdk.org> wrote:

>> **Subject**
>> Addition of Predicate-based `indexOf` and `lastIndexOf` 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.
>> 
>> The proposed methods 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.
>> 
>> Here is a brief overview of the changes made in this pull request:
>> 
>> 1. Added the `indexOf(Predicate<? super E> filter)` method to the `List` 
>> interface.
>> 2. Added the `lastIndexOf(Predicate<? super E> filter)` method to the `List` 
>> interface.
>> 3. Implemented these methods in all non-abstract classes that implement the 
>> `List` interface.
>> 
>> 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.indexOf(s -> s.contains("ct t"));
>> System.out.println(index1); // Expected output: 1
>> int index2 = list.lastIndexOf(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
>> 
>> 
>> 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 bas...
>
> side note: looks like this code have been reformated and some unused imports 
> has been reformated. jdk compiles and works just fine, so i guess its not a 
> big deal

> Hello @Evemose, if we add an API we should also consider if implementation 
> can efficiently implement it. How is this new API better than using a 
> ListIterator directly so it's worth the additional methods?

Hi, @liach ! The implementations i provided in this pull requests are pretty 
much imitating behaviour of indexOf(Object). Every class that has overriden 
indexOf(Object) recieved implementation of indexOf(Predicate) that works the 
same way except for search is based on predicate and not equality. Therefore, 
the effectiveness of implementation is straight up depends on effectiveness of 
indexOf(Object) for each separate java.util.List impl.

As for ListIterator, where suitable, it has already been used in 
implementations in classes where it was considered suitable for indexOf(Object) 
(to be more precise, in AbstractList). The main goal of this pull requst is to 
provide shorthand for developers as search for index of element that match 
predicate is very common task and providing way to do it as comfortable as 
possible should vastly enhance development expirience.

For ListIterator specifically: the main downside of its direct usage for 
developer is inability to use it fluently (as method call argument, for 
example), which forces to either implement method to find index separately or 
find it in same method as invocation but before invocation explicitly. Both 
cases are pretty frustraiting and, in my opinion, shouldn`t be neccessary for 
high-level language like Java.

Summarizing, its not that in current stdlib there are no ways to search for 
index of element based on condition, but this addition would be a great way to 
make Java development more comfortable and fast.

PS:
Also implementing indexOf with predicate is a common practice for many high 
level languages: C#/.NET has FindIndex, Kotlin has indexOfFirst, Swift has 
firstIndex etc.

-------------

PR Comment: https://git.openjdk.org/jdk/pull/18639#issuecomment-2040025647

Reply via email to