Thanks for the advice. Indeed, it was a mistake to implement this before
discussing it in mail. This is my first open-source experience, so i guess
this will be a valuable experience for my future contributions

сб, 20 апр. 2024 г. в 00:12, David Alayachew <davidalayac...@gmail.com>:

> Hello
>
> Thanks for sending this email. Your idea makes a lot of sense, but I feel
> that it only serves a very specific use case. That does not make it bad,
> but it does make it narrow.
>
> I already suggested my idea in my email to Rémi, where the index is just
> another field in the data type being streamed. Doing it this way, we can
> not only cover your use case, but the use cases of many others. It has a
> far wider reach for the same level of effort.
>
> And finally, make it a point to send an email on the mailing list and
> getting consensus BEFORE making a pull request. I am guilty of this too.
> But going out of order like this slows down the system and forces reviewers
> to take extra steps that they wouldn't have to if you had followed protocol.
>
> On Fri, Apr 19, 2024 at 5:02 PM David Alayachew <davidalayac...@gmail.com>
> wrote:
>
>>
>> No Rémi, I don't think your idea is the right approach. You are working
>> on the wrong level of abstraction.
>>
>> Many users ask requests like this all the time, and what you are
>> suggesting would be even more error-prone than the equivalent for loop or the
>> IntStream suggestion that the user above requested. Not to mention that
>> getting it to parallelize would be a task many users are likely to mess up
>> -- either in correctness or in performance.
>>
>> I think you would get far more mileage from adding 2 methods on the list
>> interface streamWithIndex() and parallelStreamWithIndex() that would return
>> a Stream<WithIndex<T>>, as opposed to just Stream<T>.
>>
>> That way, users are not writing a custom Gatherer each time they want to
>> work with the index. They just have the index be a field in the object.
>> They can work with it the same way they would any other object field.
>>
>> Furthermore, doing it this way makes the correct answer obvious. If I
>> need to do something with an index, stream with the index.
>>
>> On top of that, it significantly enhances readability by making it clear
>> to the reader that, whatever this stream is doing will require use of the
>> index, so watch out for that.
>>
>>
>>
>> On Fri, Apr 19, 2024, 1:47 PM Remi Forax <fo...@univ-mlv.fr> wrote:
>>
>>> 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. 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
>>>
>>>

Reply via email to