patternjavaModerate
One-line initialisation for a constant list with all entries except one from another list
Viewed 0 times
exceptconstantlineallwithoneforanotherlistfrom
Problem
I'm looking to simplify the initialisation of the second constant, preferably to just one line. Any ideas? Anything from Guava or JDK (up to 1.6) is ok to use.
Granted, it's not that bad, but still I'd like to get rid of the init method. :-) (Static initialiser wouldn't be any better.)
NB: I want to define the order of boxes only once, in the enum definition itself, so
A single-statement Guava solution would be this, using
Resolution
Went with this, which is the cleanest option considering I indeed need the constants defined as Lists:
Props to Xaerxess!
enum Box {
PROMO_HEADER,
FREEMIUM,
EXTRA_STORIES,
TOP_STORIES,
TOP_CHARACTERS,
TOP_THEMES,
TOP_ARTISTS,
TOP_ISSUES
// several more ...
}
final static List FREEMIUM_BOXES = ImmutableList.copyOf(Box.values());
final static List DEFAULT_BOXES = initDefaultBoxes(); // All except FREEMIUM
static List initDefaultBoxes() {
List boxes = Lists.newArrayList(FREEMIUM_BOXES);
boxes.remove(Box.FREEMIUM);
return ImmutableList.copyOf(boxes);
}Granted, it's not that bad, but still I'd like to get rid of the init method. :-) (Static initialiser wouldn't be any better.)
NB: I want to define the order of boxes only once, in the enum definition itself, so
ImmutableList.of(PROMO_HEADER, EXTRA_STORIES, ...) is not considered a good solution for the purposes of this refactoring.A single-statement Guava solution would be this, using
filter() and a Predicate, but arguably this is less clean than the original, because this kind of stuff is verbose in Java...final static List DEFAULT_BOXES =
ImmutableList.copyOf(Iterables.filter(FREEMIUM_BOXES, new Predicate() {
@Override
public boolean apply(Box box) {
return box != Box.FREEMIUM;
}
}));Resolution
Went with this, which is the cleanest option considering I indeed need the constants defined as Lists:
final static List FREEMIUM_BOXES = ImmutableList.copyOf(Box.values());
final static List DEFAULT_BOXES =
Sets.immutableEnumSet(EnumSet.complementOf(EnumSet.of(Box.FREEMIUM))).asList();Props to Xaerxess!
Solution
Use
A specialized Set implementation for use with enum types. (...) The iterator returned by the iterator method traverses the elements in their natural order (the order in which the enum constants are declared).
It's also very efficent:
Implementation note: All basic operations execute in constant time.
They are likely (though not guaranteed) to be much faster than their
HashSet counterparts. Even bulk operations execute in constant time if
their argument is also an enum set.
So in your case:
or if you prefer immutable one, use
or if you insist for
P.S. All constants can be represented as:
EnumSet for that. From docs:A specialized Set implementation for use with enum types. (...) The iterator returned by the iterator method traverses the elements in their natural order (the order in which the enum constants are declared).
It's also very efficent:
Implementation note: All basic operations execute in constant time.
They are likely (though not guaranteed) to be much faster than their
HashSet counterparts. Even bulk operations execute in constant time if
their argument is also an enum set.
So in your case:
final static Set DEFAULT_BOXES =
EnumSet.complementOf(EnumSet.of(Box.FREEMIUM));or if you prefer immutable one, use
Sets.immutableEnumSet(Iterable):final static ImmutableSet DEFAULT_BOXES =
Sets.immutableEnumSet(EnumSet.complementOf(EnumSet.of(Box.FREEMIUM)));or if you insist for
List (but why would you?):final static ImmutableList DEFAULT_BOXES =
Sets.immutableEnumSet(EnumSet.complementOf(EnumSet.of(Box.FREEMIUM))).asList();P.S. All constants can be represented as:
final static Set FREEMIUM_BOXES = EnumSet.allOf(Box.class); // or wrap it with Sets.immutableEnumSet to make it ImmutableSetCode Snippets
final static Set<Box> DEFAULT_BOXES =
EnumSet.complementOf(EnumSet.of(Box.FREEMIUM));final static ImmutableSet<Box> DEFAULT_BOXES =
Sets.immutableEnumSet(EnumSet.complementOf(EnumSet.of(Box.FREEMIUM)));final static ImmutableList<Box> DEFAULT_BOXES =
Sets.immutableEnumSet(EnumSet.complementOf(EnumSet.of(Box.FREEMIUM))).asList();final static Set<Box> FREEMIUM_BOXES = EnumSet.allOf(Box.class); // or wrap it with Sets.immutableEnumSet to make it ImmutableSetContext
StackExchange Code Review Q#39811, answer score: 10
Revisions (0)
No revisions yet.