Did this discussion get lost?

On Sun, Sep 20, 2020 at 1:27 AM Nir Lisker <nlis...@gmail.com> wrote:

> While it might not be difficult to add a find() method to Iterable, why
>> limit it to
>> the find operation, and what about all the other operations available on
>> Stream?
>
>
> Good question. I would say it's a matter of how much it is used and what
> it takes to implement it. The find operation is a lot more common than
> reduce from what I observe, for example, so I wouldn't suggest reduce to be
> added..A map(Function<T,R>) operation would require creating a new
> collection/iterable internally, and that can be messy (you could
> preemptively create and pass your own, but then I doubt the worthiness of
> it). forEach already exists. I just don't see anything enticing.
>
> Maybe what's necessary is a way to convert an Iterable to a Stream.
>
>
> Most Iterables are Collections and arrays, and these are easy to convert,
> so I'm not sure if that really helps. Besides,the idea is to avoid Stream,
> as I've mentioned, due to the cumbersomeness and the overhead of creating a
> stream. If I need to do
>
> iterable.stream().filter(person -> person.id == 123456).findAny/First()
>
> then I didn't really solve my problem.
>
> On the other hand, your examples use a list. The List interface already
>> has methods
>> indexOf/lastIndexOf which search the list for a particular object that's
>> compared
>> using equals(). It seems reasonable to consider similar methods that take
>> a
>> predicate instead of an object.
>
>
> I could have used a Set just as well. As for indexOf(Predicate<T>), I
> would say that it is useful (but personally, I hardly ever need the index
> of an object, I need the object itself). Interestingly,
> removeIf(Predicate<T>) exists, but remove(Predicate<T>) doesn't. I would
> think twice before suggesting to add it though.
>
> Ultimately, you have access to a lot of analytics and codebase scans. If
> you know which patterns are used a lot more than others it would be a good
> guide. If there are a lot of iterations in order to find an object, its
> index, or to remove it (or something else), perhaps it's worth supplying
> these methods. After all, forEach(Consumer<T>) exists and it iterates while
> calling accept(t) - not that different from iterating with test(t).
>
> P.S. lastIndexOf I find odd in the sense that it's the only method I found
> that iterates backwards, We don't have, removeLast, removeIfBackwards,
> forEachBackwards, a backwards for-each loop, or addLast (the latter is
> add(list.size()-1, e); ).
>
> - Nir
>
> On Thu, Sep 17, 2020 at 1:32 AM Stuart Marks <stuart.ma...@oracle.com>
> wrote:
>
>>
>>
>> On 9/16/20 1:59 PM, Remi Forax wrote:
>> > ----- Mail original -----
>> >> De: "Nir Lisker" <nlis...@gmail.com>
>> >> À: "core-libs-dev" <core-libs-dev@openjdk.java.net>
>> >> Envoyé: Lundi 14 Septembre 2020 20:56:27
>> >> Objet: 'Find' method for Iterable
>> >
>> >> Hi,
>> >>
>> >> This has probably been brought up at some point. When we need to find
>> an
>> >> item in a collection based on its properties, we can either do it in a
>> >> loop, testing each item, or in a stream with filter and findFirst/Any.
>> >>
>> >> I would think that a method in Iterable<T> be useful, along the lines
>> of:
>> >>
>> >> public <T> Optional<T> find(Predicate<T> condition) {
>> >>     Objects.requireNonNull(condition);
>> >>     for (T t : this) {
>> >>          if (condition.test(t)) {
>> >>              return Optional.of(t);
>> >>         }
>> >>     }
>> >>     return Optional.empty();
>> >> }
>> >>
>> >> With usage:
>> >>
>> >> list.find(person -> person.id == 123456);
>> >>
>> >> There are a few issues with the method here such as t being null in
>> >> null-friendly collections and the lack of bound generic types, but this
>> >> example is just used to explain the intention.
>> >>
>> >> It will be an alternative to
>> >>
>> >> list.stream().filter(person -> person.id == 123456).findAny/First()
>> >> (depending on if the collection is ordered or not)
>> >>
>> >> which doesn't create a stream, similar to Iterable#forEach vs
>> >> Stream#forEach.
>> >>
>> >> Maybe with pattern matching this would become more appetizing.
>> >
>> > During the development of Java 8, we first tried to use
>> Iterator/Iterable instead of using a novel interface Stream.
>> > But a Stream cleanly separate the lazy side effect free API from the
>> mutable one (Collection) and can be optimized better by the VM (it's a push
>> API instead of being a pull API).
>> >
>> > The other question is why there is no method find() on Collection, i
>> believe it's because while find() is ok for any DB API, find() is dangerous
>> on a Collection because the execution time is linear, so people may use it
>> instead of using a Map.
>>
>>
>> Hi Nir,
>>
>> Rémi is correct to point out this distinction between the lazy operations
>> (which
>> appear on Stream) and the eager (and possibly mutating) operations on
>> Collections. I
>> think we want to preserve this distinction.
>>
>> While it might not be difficult to add a find() method to Iterable, why
>> limit it to
>> the find operation, and what about all the other operations available on
>> Stream?
>> Maybe what's necessary is a way to convert an Iterable to a Stream. In
>> fact, this is
>> already possible:
>>
>>      StreamSupport.stream(iterable.spliterator(), false)
>>
>> Well, this is mouthful, so maybe there ought to be an easier way to
>> convert an
>> Iterable to a Stream.
>>
>> On the other hand, your examples use a list. The List interface already
>> has methods
>> indexOf/lastIndexOf which search the list for a particular object that's
>> compared
>> using equals(). It seems reasonable to consider similar methods that take
>> a
>> predicate instead of an object.
>>
>> Does either of these sound promising?
>>
>> s'marks
>>
>

Reply via email to