firstNonEmpty functionality

72 views
Skip to first unread message

Ivan Hristov

unread,
Feb 22, 2012, 9:52:37 AM2/22/12
to guava-discuss
Hi guys,

Since there is already an Objects.firstNonNull(T first, T second)
functionality, I was wondering if you have thought about adding
Objects.firstNonEmpty(Collection<T> first, Collection<T> second) ?

Cheers,
Ivan

Sean P. Floyd

unread,
Feb 23, 2012, 3:57:27 AM2/23/12
to guava-discuss
I'm guessing the place for this would be

Collections2.firstNonEmpty(Collection<T> first, Collection<T> second)

but it doesn't really feel like something that's needed that often.
Perhaps it would make more sense to add an empty() Predicate:

public static Predicate<? extends Collection<?>> Predicates.empty()

Then you could do this:

Iterables.find(Arrays.asList(firstCollection, secondCollection),
Predicates.not(Predicates.empty()))

But it would still be quite a monster compared to this:

Collection<?> which = first.isEmpty() ? second : first;

or

Collection<?> which = first.isEmpty() ? (second.isEmpty() ?
Collections.emptySet() : second) : first;

Ivan Hristov

unread,
Feb 23, 2012, 4:22:24 AM2/23/12
to guava-discuss
Hi Sean,

The ultimate goal would be to avoid checking if the collection is null
or empty in a simple way. The first part is easily solved by:

Collection<T> notNullCollection =
Objects.firstNonNull(possiblyNullOrEmptyCollection,
fallbackCollection);

But then the second part will involve checking for emptiness:
notNullCollection.isEmpty() ? fallbackCollection : notNullCollection;

The predicate approach is not bad, but I find it too verbose. A simple
utility method (like the Objects.firstNonNull(T first, T second) )
would suffice from my point of view.

As for your argument that it may not feel needed that often, I can
only argue that it depends on the context and the environment within
which one is working. The same argument is valid for
Objects.firstNonNull(T first, T second), if one is working in a NULL-
safe environment. However, such an environment is hard to build if
you're using a lot of (external) libraries and frameworks.

Emily Soldal

unread,
Feb 23, 2012, 7:01:42 PM2/23/12
to guava-discuss
Could I suggest the following (and please mind any mistakes, coding on
a phone isn't amazing) ;

Predicates:

public static <T extends Iterable> Predicate<T> isEmpty() {
return IsEmpty. instance. toNarrowType() ;
}
enum IsEmpty implements Predicate<Iterable<Object> > {

instance;
public boolean apply(Iterable<Object> in) {
return Iterables. isEmpty(in);
}
}

I feel this solves the problem for the broadest range of inputs.

Louis Wasserman

unread,
Feb 24, 2012, 11:15:25 AM2/24/12
to Ivan Hristov, guava-discuss
I'm not sure I can imagine what your fallback collection would be, other than another empty collection...?

(Also, isNullOrEmpty does not appear to be in the Idea Graveyard, but I suspect it should be, based on this thread.)

Ivan Hristov

unread,
Feb 24, 2012, 3:44:55 PM2/24/12
to guava-discuss
Hi Louis,

> I'm not sure I can imagine what your fallback collection would be, other
> than another empty collection...?

Say you have two sources of collections and you want to use the first
which gives you a non empty (and not null) collection. I let to your
imagination any other possible use.

> (Also, isNullOrEmpty does not appear to be in the Idea Graveyard, but I
> suspect it should be, based on this
> thread<http://groups.google.com/group/guava-discuss/browse_thread/thread/2be...>
> .)

Let me first say that I completely agree with what Kevin Bourrillion
is saying in the thread you mentioned. Quoted below:

<< Right; the reason to allow a collection reference to be null is
because that
carries some actual distinct meaning from an empty collection, such as
"not
applicable", "not yet initialized", or whatever (and that distinction
is
important). The need for that should pretty rare, though. >>

As a matter of fact the same statement is valid for any object, not
just collections. I see your point (and correct me if I am wrong), a
method with the name
Objects.firstNonEmpty(Collection<T> first, Collection<T> second)
would mean that eventually null reference for the first collection is
going the implicitly threat it as being empty. Sometimes you don't
really care if it's null or empty so a simple javadoc over the method
explaning that subtlety would help.

In the end, the discussion here is not about should we use null
reference for collections to mean that the collection is empty. After
all, most of us are living in free countries and can do whatever they
feel like doing. The discussion is more about dealing with
unacceptable state (null or empty) and not having to deal with them
separately.



On Feb 24, 5:15 pm, Louis Wasserman <wasserman.lo...@gmail.com> wrote:
> I'm not sure I can imagine what your fallback collection would be, other
> than another empty collection...?
>
> (Also, isNullOrEmpty does not appear to be in the Idea Graveyard, but I
> suspect it should be, based on this
> thread<http://groups.google.com/group/guava-discuss/browse_thread/thread/2be...>
> .)
>
> Louis Wasserman
> wasserman.lo...@gmail.comhttp://profiles.google.com/wasserman.louis

Louis Wasserman

unread,
Feb 24, 2012, 3:55:57 PM2/24/12
to Ivan Hristov, guava-discuss
On Fri, Feb 24, 2012 at 2:44 PM, Ivan Hristov <hrist...@gmail.com> wrote:
Hi Louis,

> I'm not sure I can imagine what your fallback collection would be, other
> than another empty collection...?

Say you have two sources of collections and you want to use the first
which gives you a non empty (and not null) collection. I let to your
imagination any other possible use.

Okay.  I guess I'm just concerned that this wouldn't be used broadly enough, in which case projects that really need this for their particular use case can roll their own utility methods.

Ivan Hristov

unread,
Feb 24, 2012, 4:23:29 PM2/24/12
to guava-discuss
That's always a concern. A simple voting system should resolved these
issues. To some extend that's the purpose of this discussion. It would
be nice to have a voting system though.

On Feb 24, 9:55 pm, Louis Wasserman <wasserman.lo...@gmail.com> wrote:

Louis Wasserman

unread,
Feb 24, 2012, 4:37:16 PM2/24/12
to Ivan Hristov, guava-discuss
We do frequently measure interest in issues on the issue tracker by counting the number of people who have starred them.  This is a pretty rough heuristic, but it's reasonably effective over the long term.

Colin Decker

unread,
Feb 24, 2012, 4:39:43 PM2/24/12
to Ivan Hristov, guava-discuss
I'm in agreement with Louis and Sean that this feels like a pretty niche utility. I can't really think of any cases where I would have wanted something like this. Objects.firstNonNull() is useful for the case of replacing a null result (say, a null Collection reference returned by an API you don't have control of) with a default value (an empty Collection). Such cases are at least somewhat common even if you avoid allowing nulls in your code, and what's more firstNonNull() is a tool to help you avoid nulls in your code (by making it easy to convert nulls the moment they enter). I don't really see the proposed firstNonEmpty() method having the same utility.

-- 
Colin


Kevin Bourrillion

unread,
Feb 24, 2012, 4:42:12 PM2/24/12
to Louis Wasserman, Ivan Hristov, guava-discuss
Mmmm... this statement can be misleading in a dozen ways, Louis.  I don't think users can at all assume that a star is a vote in favor, or that votes help us decide things (as opposed to reminding us what things may need our attention.)



--
Kevin Bourrillion @ Google
Java Core Libraries Team
http://guava-libraries.googlecode.com

Louis Wasserman

unread,
Feb 24, 2012, 4:45:40 PM2/24/12
to Kevin Bourrillion, Ivan Hristov, guava-discuss
Agreed -- I primarily meant that we use a star as a weak signal of "interest in an issue," pro or con or whatever, which is much more related to "what needs our attention" than it is to "what we eventually decide to do with this issue."  Apologies if that wasn't clear.

Ivan Hristov

unread,
Feb 25, 2012, 5:36:48 AM2/25/12
to guava-discuss
Indeed usability is a leading criteria. What should be the usability
of a feature in order to enter guava? At least 0.7%, 7% or 70% ? Are
all guava features fulfilling this threshold? Some projects may use
only the com.google.common.collect package, others may use a bit of
functionality from every package. Targeting different domains and
having different dimensions within the same library is both a blessing
and a curse. Projects for which final deployable size matters require
only the things that are used, on the other hand projects with no size
restriction may benefit having everything in one place. As for the
Objects.firstNonEmpty(Collection<T> first, Collection<T> second) , I
certainly don't have a marketing research report and thus I cannot
argue if this is going to be niche utility or not.

Colin Decker

unread,
Feb 25, 2012, 9:44:53 AM2/25/12
to Ivan Hristov, guava-discuss
As to projects where the deployable size matters: Guava's recommendation is to use ProGuard (http://code.google.com/p/guava-libraries/wiki/UsingProGuardWithGuava) with your build. This will strip out everything that's unused from your final artifact so that you actually do minimize the size. As such, the issue of Guava's jar size isn't really a concern in deciding whether or not to include a method like this. The issue is just whether or not a method has enough common use cases and whether it really would simplify the code it replaces enough to justify inclusion. As I said, my initial impression is that this method wouldn't meet that criteria... particularly given that just writing out "first.isEmpty() ? second : first" is such an easy alternative.

-- 
Colin


Louis Wasserman

unread,
Mar 1, 2012, 12:41:35 PM3/1/12
to Ivan Hristov, guava-discuss
The most relevant metric to the Guava team is, more or less, utility times ubiquity.

So at one extreme, Guava ends up containing features with great utility to a narrow set of users, e.g. MinMaxPriorityQueue -- an extremely nontrivial data structure, but when you need it, you really need it -- and on the other end, you get tiny features that are used basically everywhere, like Lists.newArrayList, a one-liner whose primary reason for existence is saving Java 6 users a few generic arguments.  (And then you get things like Multiset, which have great utility and great ubiquity!)

In terms of "marketing research reports," Guava has Google's entire Java codebase to examine for use cases, and when we're particularly unsure as to the utility of a method, we do those studies, ourselves, personally; we're not handed them by some marketing team.  Certainly it's a somewhat subjective call: what if a method has five users?  Ten?  Twenty?  If those numbers don't answer the question, then we discuss it some more.  Frequently, we decide to hold off on adding the method unless more users surface.

But we always make the comparison with the workarounds that are already available.  In this case, the workaround is "collection.isEmpty() ? fallback : collection;" which is not, all things considered, a bad workaround at all.  

Those rare times I can remember personally having to special-case an empty collection, it typically deserved an if/else of its own, and sometimes a comment.  But those occasions were relatively rare, compared to the other one-line utility methods Guava provides. 

Ivan Hristov

unread,
Mar 1, 2012, 2:47:03 PM3/1/12
to guava-discuss
@ Colin

Thanks for the ProGuard tip. Indeed, first.isEmpty() ? second : first
is an easy alternative, the irritation comes after the second time you
reapeat it in more than two projects.

@ Louis

Thanks for the concrete answer ("...utility times ubiquity..."). It's
much more solid than any feelings expressed on a given topic. Once
again, I agree that "collection.isEmpty() ? fallback : collection;"
is not a bad workaround as long as it does not appear several times in
different project, then it becomes like an itch.

I consider the discussion for closed if you really have tried what
I've proposed against “the Google's entire Java code base to examine
for use cases” and you have found no common use. Please, accept my
apologies for taking your time.

Ivan

On Mar 1, 6:41 pm, Louis Wasserman <wasserman.lo...@gmail.com> wrote:
> The most relevant metric to the Guava team is, more or less, utility times
> ubiquity.
>
> So at one extreme, Guava ends up containing features with great utility to
> a narrow set of users, e.g. MinMaxPriorityQueue -- an extremely nontrivial
> data structure, but when you need it, you *really* need it -- and on the
> other end, you get tiny features that are used basically everywhere, like
> Lists.newArrayList, a one-liner whose primary reason for existence is
> saving Java 6 users a few generic arguments.  (And then you get things like
> Multiset, which have great utility *and* great ubiquity!)
>
> In terms of "marketing research reports," Guava has Google's entire Java
> codebase to examine for use cases, and when we're particularly unsure as to
> the utility of a method, we *do* those studies, ourselves, personally;
> we're not handed them by some marketing team.  Certainly it's a somewhat
> subjective call: what if a method has five users?  Ten?  Twenty?  If those
> numbers don't answer the question, then we discuss it some more.
>  Frequently, we decide to hold off on adding the method unless more users
> surface.
>
> But we always make the comparison with the workarounds that are already
> available.  In this case, the workaround is "collection.isEmpty() ?
> fallback : collection;" which is not, all things considered, a bad
> workaround at all.
>
> Those rare times I can remember personally having to special-case an empty
> collection, it typically deserved an if/else of its own, and sometimes a
> comment.  But those occasions were relatively rare, compared to the other
> one-line utility methods Guava provides.
>
> Louis Wasserman
> wasserman.lo...@gmail.comhttp://profiles.google.com/wasserman.louis
> > > > To get help:http://stackoverflow.com/questions/ask(usethe tag
Reply all
Reply to author
Forward
0 new messages