Note on java.util.functions
Brian Goetz
brian.goetz at oracle.com
Tue May 22 10:05:01 PDT 2012
Either the name getFirst and getOnly are probably fine for their
semantics, but the conjunction of the two is definitely confusing. I
would think that getFirst/getAny should probably have "find" in their
name.
Its worth noting that these methods are where laziness pays off most
obviously; doing a find-first on a filtered list where the filter is
expensive only evalutes the filters on enough elements to find one.
Summary:
getFirst -- find the first element of the stream in encounter order. If
none is available, return (non-exceptional) indication of same.
getOnly -- get the sole element of the stream; throw an exception if the
stream has zero elements or more than one element. This allows you to
enforce a programmatic invariant at the same time as computing the answer.
getAny -- find any element of the stream. (For sequential streams, this
is likely to be identical to getFirst.)
Any of these can be parallelized, to varying benefit, on finite streams.
The one that shows the most parallel benefit is likely to be getAny,
though for streams involving highly selective filters or expensive
per-element computation, getFirst/getOnly may well show some speedup.
On 5/22/2012 12:51 PM, David Conrad wrote:
>
>
> On Tue, May 22, 2012 at 10:16 AM, Brian Goetz <brian.goetz at oracle.com
> <mailto:brian.goetz at oracle.com>> wrote:
>
> Thanks for reviewing.
>
> > Iterables.getFirst() and Iterators.getFirst() should throw
> > NoSuchElementException if there are no elements, not return null,
> which is
> > a perfectly valid element in some collections. Also, they should
> just be
> > named first(), IMHO.
>
> Except that is not their intended semantics. The intended semantics
> is that they be find-first, where "not found" is an expected
> condition. One possibility for making this clearer is to return
> something like Guava's Option.
>
> Ultimately this comment is indicative of bad naming; obviously
> "getFirst" suggests to you (and probably others) that there must be
> a first element, maybe this should be called "findFirst" or
> something like that. It is made worse by the fact that getOnly
> *does* throw. The assymmetry is deliberate; one is a way of
> asserting the Iterable has exactly one element (getOnly); the other
> is a way of saying "get me the first one if there is any; I don't
> care if there are more." Both are important use cases, but probably
> should be named differently.
>
>
> Ah, okay. It's partly due to their naming but also partly due to the
> fact that I needed something similar a short while back. But in my case
> I happened to want to return just the smallest (first) item in a
> TreeSet<Integer>, and so I had:
>
> public static <T> T first(Iterable<T> sequence) {
> return sequence.iterator().next();
> }
>
> and:
>
> System.out.println(first(set));
>
> This actually came up a few times, and so when I saw getFirst() I
> naturally thought that's what it was. So maybe you should think about
> changing the name, but maybe it was just me.
>
> Cheers,
> David
>
More information about the lambda-dev
mailing list