按值查找枚举的正确方法

Ray*_*Ray 11 java enums

我有几个Java枚举,看起来像下面(为机密性编辑等).在每种情况下,我都有一个我真的不满意的查找方法; 在下面的例子中,它是findByChannelCode.

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是,当我可以使用a时,我觉得这些线性查找很傻HashMap<String, PresentationChannel>.所以我想到了下面的解决方案,但是我希望它有点混乱,而且更重要的是,我肯定在别人遇到这个问题时我不在乎重新发明轮子.我想得到这个群体的一些圣人智慧:用值索引枚举的正确方法是什么?

我的解决方案

ImmutableMap<String, PresentationChannel> enumMap = Maps.uniqueIndex(ImmutableList.copyOf(PresentationChannel.values()), new Function<PresentationChannel, String>() {
        public String apply(PresentationChannel input) {
            return input.getChannelCode();
        }});
Run Code Online (Sandbox Code Playgroud)

并且,在枚举中:

public static PresentationChannel findByChannelCode(String channelCode) {
     return enumMap.get(channelCode);
}
Run Code Online (Sandbox Code Playgroud)

Puc*_*uce 5

我想你在这里使用的是非JDK类吗?

与JDK API类似的解决方案:

private static final Map<String, PresentationChannel> channels = new HashMap<String, PresentationChannel>();

static{
  for (PresentationChannel channel : values()){
    channels.put(channel.getChannelCode(), channel);
  }
}
Run Code Online (Sandbox Code Playgroud)


gus*_*afc 5

我想得到这个群体的一些圣人智慧:用值索引枚举的正确方法是什么?

很可能根本不这样做.

虽然哈希表提供O(1)查找,但它们也有相当大的常量开销(用于哈希计算等),因此对于小型集合,线性搜索可能更快(如果"有效方式"是您对"正确方法"的定义).

如果你只是想要一个干嘛的方式来做,我认为番石榴Iterables.find是另一种选择:

return channelCode == null ? null : Iterables.find(Arrays.asList(values()),
    new Predicate<PresentationChannel>() {
        public boolean apply(PresentationChannel input) {
            return input.getChannelCode().equals(channelCode);
        }
    }, null);
Run Code Online (Sandbox Code Playgroud)