I have this weird scenario in which some Java property is used to build and HQL query, and the type of the field is Boolean
, i.e. it is boxed. I wondered why because I don't really like to think of booleans as having three possible values, true
, false
, and null
. I recently found out the null
value actually has semantics in this system. The semantics are: true
means "only unviewed", false
means "only viewed", and null means "all". So, if null, the field is ignored when building the HQL query, so that the end result contains both unviewed and viewed results.
In my opinion this is a case where an enum should be used. Something like this:
enum ViewStatus {
VIEWED, UNVIEWED;
}
My dilemma now is what to use for the third case that should represent the union of these two constants? The two options are:
-
Introduce a third enum constant,
ALL
.enum ViewStatus { VIEWED, UNVIEWED, ALL; }
-
Use an
EnumSet
.
EnumSet
pretty much exists specifically for this purpose, but… it seems like just two much overhead. Especially when reading the values in the part of the code that builds the HQL.
So, what are your thoughts? Shall I go with a third enum constant and refactor to EnumSet
when need arises?
Thanks!
Update
I'll go for an EnumSet
because I want to introduce methods on that enum that wouldn't make sense to be called on ALL
. For example ViewStatus.isViewed()
.
Best Answer
I rather avoid things like
since it introduces a new class without giving you anything in return when compared to
But that's a matter of personal taste.
By setting the reference to
null
you can have a third value, which is not really good, since you can get an unexpectedNPE
somewhere;null
is just no "first class value".The overhead of an
EnumSet
is reasonable, it caches the class and an array of all values, and uses along
for storing the data (as long as theenum
is small enought). Itsequals
method is quite fast, but obviously slower than reference comparison. You mentioned using HQL, so most probably the runtime will be dominated by the database access, so IMHO you're needless and premature optimization.The mutability of the
EnumSet
may be a problem sometimes, but there's ImmutableEnumSet in guava.I don't think you stated all your alternatives right. You can have both
and
where the second is an replacement for the
EnumSet
. That said, I agree with your decision.