2011-05-29 58 views
1

我希望能够以编程方式为每个密钥指定密钥列表和允许的值,以便可以在编译时检查代码中的错误并希望获得更好的性能。我可以在枚举中声明枚举以指定/限制Java中的映射中的键和值吗?

想象我代表字在数据库中,每个字有许多特点:

public class Word { 

    public Map<Feature, FeatureValue> features = new EnumMap<Feature, FeatureValue>(); 

} 

而且我有一个枚举类:

public enum Feature { 

    TYPE("Type") { 

    enum Value { 
    NOUN("Noun"), 
    VERB("Verb"); 
    } 

    @Override 
    public Value[] getValues() { 
    return new Value[]{Value.NOUN, Value.VERB}; 
    } 

}, 


    PLURALITY("Plurality") { 

    enum Value { 
    SING("Singular"), 
    PL("Plural"); 
    } 

    @Override 
    public Value[] getValues() { 
    return new Value[]{Value.SING, Value.PL}; 
    } 

}, 

} 

我至少希望能够做类似的事情:

word.features.put(TYPE,TYPE.VALUE.NOUN); word.features.put(PLURALITY,PLURALITY.Value.PL);

因此,很容易看出这些值与键匹配,但枚举语法中的枚举似乎不被允许。

我也试过这样:

TYPE("Type") { 

public String NOUN = "Noun"; 
public String VERB = "Verb"; 

但由于它们不能是静态出于某种原因我无法引用TYPE.NOUN。

请有人知道一个很好的模式来指定这样的东西?我只是担心,如果在我的代码一样

word.features.put(TYPE, "Noun"); 

使用字符串我找麻烦用错别字等

回答

1

你不能那样做,但你可以做这样的:

// define a type values as an enum: 
enum TypeValue { 
    Noun, Verb 
} 

// define an attribute class parametrized by an enum: 
public class Attribute<E extends Enum<E>> { 

    // define your attribute types as static fields inside this class 
    public static Attribute<TypeValue> Type = new Attribute<TypeValue>(); 
} 

// and now define your method like this: 
<E extends Enum<E>, Feature extends Attribute<E>> void put(Feature feature, E value) { 
} 

// you will then have a compilation error when trying to invoke the method with improper associated parameters. 

// eg if we define 
enum OtherValue { X } 

features.put(Attribute.Type, TypeValue.Noun); // ok 
features.put(Attribute.Type, OtherValue.X); // Fails 
+0

Thanks Toader!我会试试这个。我不太明白,Feature类在哪里?我不能只用: 'E扩展枚举,属性> void put(属性功能,E值){' – 2011-05-30 10:10:44

+0

这是我最初的想法:)。如果你想使它更简单,你应该一路走下去:'E扩展枚举> void put(属性特征,E值)' – 2011-05-30 15:17:59