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 >>> >>>