【问题标题】:Reverse lookup for Java Enums with more than one value per key/constant?反向查找每个键/常量多个值的 Java 枚举?
【发布时间】:2014-10-13 10:51:16
【问题描述】:

使用像这样的枚举,其中每个键都有多个值

ABBR1("long text 1", "another description 1", "yet another one 1"), 
ABBR2("long text 2", "another description 2", "yet another one 2"), 
//and so on...

如何通过调用getAbbreviation(descriptionText) 之类的方法来反向查找缩写(常量)?

我想我基本上是在寻找here 描述的实现,但不同的是每个 ENUM 键(常量)都有几个值,我希望它也可以与 getAbbreviation("long text 1") 一起使用与getAbbreviation("yet another one 2")...

是否有一种简单的方法可以遍历每个 ENUM(即ABBRn)的值字段,以填充巨大的地图,或者是否有更好的解决方案?

【问题讨论】:

    标签: java enums lookup reverse-lookup


    【解决方案1】:

    这依赖于枚举成员构造函数在静态初始化程序之前运行的事实。然后初始化器缓存成员及其长格式。

    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.Map;
    
    public enum Abbreviation {
        ABBR1("long text 1", "another description 1", "yet another one 1"), 
        ABBR2("long text 2", "another description 2", "yet another one 2"); 
    
        private static final Map<String, Abbreviation> ABBREVIATIONS = new HashMap<>();
    
        private String[] longForms;
        private Abbreviation(String... longForms) {
            this.longForms = longForms;
        }
    
        public String toString () {
            return Arrays.toString(longForms);
        }
    
        static {
            for(Abbreviation abbr : values()) {
                for(String longForm : abbr.longForms) {
                    ABBREVIATIONS.put(longForm, abbr);
                }
    
            }
        }
    
        public static Abbreviation of(String longForm) {
            Abbreviation abbreviation = ABBREVIATIONS.get(longForm);
            if(abbreviation == null) throw new IllegalArgumentException(longForm + " cannot be abbreviated");
            return abbreviation;
        }
    
    
    
        public static void main(String[] args) {
            Abbreviation a =  Abbreviation.of("yet another one 2");
            System.out.println(a == Abbreviation.ABBR2); //true
        }
    }
    

    【讨论】:

    • 如果我需要为每个参数的构造函数提供参考,我需要改变什么,例如private Abbreviation(String longText, String desc1, String desc2) { this.longText = longText; //etc?我猜for(String longForm : abbr.longForms) 不会为此工作?
    • 我认为每个缩写都可以有可变数量的长形式。由于您有固定数量的参数,因此您需要为每个枚举成员构造一个包含所有 3 个参数的数组。 private Abbreviation(String longText, String desc1, String desc2) { this.longForms = new String[] {longText, desc1, desc2}; }
    • 那么,没有内置的方法来循环一个(即一个)ENUM 常量的值吗?
    【解决方案2】:

    每个枚举都有一个方法 values() 所以你可以这样做:

    for(YourEnum type : values()){
            if(/*is Equal to Your descriptionText*/){
                 return type;
            }
        }
        throw new IllegalArgumentException("No such BailiffPaymentStatus:"+dbRepresentation);
    

    【讨论】:

    • 你知道values()方法定义的Java类是什么吗?是java.lang Enum中的那个吗?如果是这样,该类必须描述一个 ENUM 常量及其值 - 这会引发枚举“类”在哪里定义的问题......?
    • 是的,它是在 Enum 类本身中定义的。如果您要反编译您的枚举,您会注意到这或多或少是一个非常简单的类theopentutorials.com/tutorials/java/enum/…
    • @Christian java.lang.Enum中没有values()方法,是实际枚举类型的合成方法。
    • @kapep:我假设类型本身是用 Java 实现的?如果是这样,有没有办法查看源代码?只是好奇……
    • @Christian 是编译器生成的,所以我认为你找不到真正的源文件。不过,java 规范应该包含一些关于它的信息,您可以使用 javap 查看代码 - 或者只查看 maslan 发布的链接中的代码,这是一个非常简单的方法,只返回一个枚举常量数组。
    【解决方案3】:

    我认为来自 c.P.u1 的解决方案是正确的。但是,当您使用这个问题的解决方案时,有一种更直接的方法来填充 HashMap。

    • How to facilitate Netbeans Designer to load JPanel-s that use an enum reverse-lookup using hashmap?

          private static final Map<String, Abbreviation> abbreviationMap;
      
          private Abbreviation(String... longForms) {
              this.longForms = longForms;   //  optional
              mapAbbreviations( this, longForms )
          }
      
          private static void mapAbbreviations( final Status state, String... longForms ){
              if( null ==  abbreviationMap  ){
                  abbreviationMap  = new HashMap( 20 );
              }
              for( String abbrev : longForms ){
                  abbreviationMap.put( abbrev,  state );
              }
          }
      

    另外,toString() 函数不需要私有的 longForms 字符串数组,因为所有值都保存在 Map 中。

    【讨论】:

      猜你喜欢
      • 2011-07-16
      • 2014-07-17
      • 2015-08-21
      • 2015-01-26
      • 2011-08-17
      • 2015-06-20
      • 1970-01-01
      • 1970-01-01
      • 2011-07-09
      相关资源
      最近更新 更多