Java – the correct way to find enumerations by value
I have several Java enumerations that look like the following (edit for confidentiality, etc.)
public enum PresentationChannel { ChannelA("A"),ChannelB("B"),ChannelC("C"),ChannelD("D"),ChannelE("E"); private String channelCode; PresentationChannel(String channelCode) { this.channelCode = channelCode; } public String getChannelCode() { return this.channelCode; } public PresentationChannel findByChannelCode(String channelCode) { if (channelCode != null) { for (PresentationChannel presentationChannel : PresentationChannel.values()) { if (channelCode.equals(presentationChannel.getChannelCode())) { return presentationChannel; } } } return null; } }
The problem is that when I can use HashMap < string, presentationchannel >, I think these linear lookups are stupid So I came up with the following solution, but I hope it's a bit messy. More importantly, when someone encounters this problem, I don't care about reinventing the wheel I want to get some sage wisdom from this group: what is the correct way to enumerate by value index?
My solution
ImmutableMap<String,PresentationChannel> enumMap = Maps.uniqueIndex(ImmutableList.copyOf(PresentationChannel.values()),new Function<PresentationChannel,String>() { public String apply(PresentationChannel input) { return input.getChannelCode(); }});
And in the enumeration:
public static PresentationChannel findByChannelCode(String channelCode) { return enumMap.get(channelCode); }
Solution
It is entirely possible that this was not done
Although hash tables provide o (1) lookup, they also have considerable constant overhead (for hash calculation, etc.), so linear search may be faster for small sets (if the "effective method" is the "definition" method)
If you just want a dry way to do it, I assume guava's iterables Find is another option:
return channelCode == null ? null : Iterables.find(Arrays.asList(values()),new Predicate<PresentationChannel>() { public boolean apply(PresentationChannel input) { return input.getChannelCode().equals(channelCode); } },null);