On Fri, 5 Apr 2024 00:00:58 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 based on your suggestions.
> 
> Thank you for considering this proposal.
> 
> Best regards

A few remarks:
1. The concern on `indexOf(Object)` and `indexOf(Predicate)` is valid; 
`Optional` has `orElse` vs. `orElseGet` to avoid these clashes. The behavior 
change of `indexOf(null)` is a source incompatibility.
2. Have you considered `indexOf(predicate/object, startIndex)` like the indexOf 
for `String`?

Also, a significant difference between String/arrays and `List` is that `List` 
is structurally modifiable; the index may be no longer valid after a 
modification. Thus the index is not as useful. 

For example, in an [unrolled linked 
list](https://en.wikipedia.org/wiki/Unrolled_linked_list) implementation, each 
block can be independently locked for read/write access, maybe like this:
`[1, 2, 3] -> [4, 5] -> [6, 7, 8, 9]`
An index would be useless if any part of this list updates, but if the position 
information is stored in a `ListIterator` and we add an `beforeNext(predicate)` 
that moves the cursor to right before the next element that matches the 
predicate (or the tail if there's no match), this would be much more useful.

Just a side note, this patch won't be reviewed by official JDK engineers until 
it has rfr tag (means this PR is not draft and the automatic checks of issue, 
whitespace, oca etc. are passed)

You should post on `core-libs-dev@openjdk.org` to get feedbacks on the API 
design, too.

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

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

Reply via email to