Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 枚举集的最佳初始化<;E>;由E的实例持有_Java_Enums_Static Initialization_Enumset - Fatal编程技术网

Java 枚举集的最佳初始化<;E>;由E的实例持有

Java 枚举集的最佳初始化<;E>;由E的实例持有,java,enums,static-initialization,enumset,Java,Enums,Static Initialization,Enumset,我正在处理一些关于我使用了部分模型的不安全(无类型安全)字符串或int表示的地方的工作。, 以及利用Enum和EnumSet最佳实践 一个特别的困难是这个用例:一个枚举,其中每个实例都有一个自己姐妹的[0..n]枚举集 为了把它归结为要点,我的问题基于Joshua Bloch的StyleEnum。所以我们得到了粗体、斜体、下划线和删除线的枚举。。让我们想象一个B_和I,它将容纳{粗体,斜体} 请不要太在意这个毫无意义的例子:在真实的系统中,这个子集是建立在@startup time加载的一些变化

我正在处理一些关于我使用了部分模型的不安全(无类型安全)字符串或int表示的地方的工作。, 以及利用Enum和EnumSet最佳实践

一个特别的困难是这个用例:一个枚举,其中每个实例都有一个自己姐妹的[0..n]枚举集

为了把它归结为要点,我的问题基于Joshua Bloch的StyleEnum。所以我们得到了粗体、斜体、下划线和删除线的枚举。。让我们想象一个B_和I,它将容纳{粗体,斜体}

请不要太在意这个毫无意义的例子:在真实的系统中,这个子集是建立在@startup time加载的一些变化规则的基础上的

目标是,一旦进行了这种计算,就不能改变实例特定的子枚举集范围。 所以我有这样的想法:

public enum StyleEnum {
    NONE(0, "none"), BOLD(100, "B"), ITALIC(250, "i"), UNDERLINE(350, "u"), STRIKETHROUGH(9, "b"), B_AND_I(99,"Emphase");

//// Pure dream  ==   private final EnumSet<StyleEnum> complexComputedSubSet = new EnumSet<StyleEnum> ();  
//// But not in the jdk  
    private final EnumSet<StyleEnum> complexComputedSubSet;
    private final int intProp;
    private final String strLabel;

    StyleEnum(int intProp, String strLabel) {
        this.intProp = intProp;
        this.strLabel = strLabel;
//// option 2 would have been be this        
//        complexComputedSubSet = EnumSet.of(NONE);
//// But COMPILER :: illegal reference to static field from initializer

    }//.... end of constructor


    /**
     * static initialzer will compute based on some rules a subset of (none) or
     * others Enum, a particular enum instance can holds in his bag.
     */
    static {
//// at least, as option 3, why not this...        
//        for (StyleEnum e : EnumSet.allOf(StyleEnum.class)) {
//            e.complexComputedSubSet = EnumSet.of(NONE);
//        }
//// COMPILER :: cannot assign a value to final variable complexComputedSubSet

        // main handling here : at class loading 
        // compute a set (rules coming from whatever you want or can).
        //Once this static class level init is done
        // nothing can change the computed EnumSet
        // it's getter will always return an unmodifiable computed EnumSet 
        //.... computing something
    }


    //....
    //getter(){}
    //whateverelse(){}

}
然后才计算并存储子枚举集

所以,所有这些痛苦,主要是因为不能说“newenumset();”?
一定有更好的办法?您能给我指出一个好的方向吗?

我会放弃在实例字段中保留辅助集,而是将其作为静态映射来实现:

import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.EnumMap;
import java.util.EnumSet;

public enum StyleEnum {
    NONE(0, "none"),
    BOLD(100, "B"),
    ITALIC(250, "i"),
    UNDERLINE(350, "u"),
    STRIKETHROUGH(9, "b"),
    B_AND_I(99,"Emphase");

    private static Map<StyleEnum, Set<StyleEnum>> complexSubsets;

    private final int intProp;
    private final String strLabel;

    StyleEnum(int intProp, String strLabel) {
        this.intProp = intProp;
        this.strLabel = strLabel;
    }

    public Set<StyleEnum> getComplexSubset() {
        initSubsets();
        return complexSubsets.get(this);
    }

    private static void initSubsets() {
        if (complexSubsets == null) {
            Map<StyleEnum, Set<StyleEnum>> map = new EnumMap<>(StyleEnum.class);
            map.put(NONE, Collections.unmodifiableSet(EnumSet.of(
                BOLD, ITALIC)));
            map.put(BOLD, Collections.unmodifiableSet(EnumSet.of(
                UNDERLINE)));
            map.put(ITALIC, Collections.unmodifiableSet(EnumSet.of(
                UNDERLINE)));
            map.put(UNDERLINE, Collections.emptySet());
            map.put(STRIKETHROUGH, Collections.unmodifiableSet(EnumSet.of(
                NONE)));
            map.put(B_AND_I, Collections.unmodifiableSet(EnumSet.of(
                BOLD, ITALIC)));
            complexSubsets = Collections.unmodifiableMap(map);

            assert complexSubsets.keySet().containsAll(
                EnumSet.allOf(StyleEnum.class)) :
                "Not all values have subsets defined";
        }
    }
}
import java.util.Collections;
导入java.util.Map;
导入java.util.Set;
导入java.util.EnumMap;
导入java.util.EnumSet;
公共枚举样式枚举{
无(0,“无”),
粗体(100,“B”),
斜体(250,“i”),
下划线(350,“u”),
删除线(9,“b”),
B_和I(99,“强调”);
私有静态映射复合子集;
私人最终int intProp;
私有最终字符串标签;
StyleEnum(int intProp,字符串strLabel){
this.intProp=intProp;
this.strLabel=strLabel;
}
公共集getComplexSubset(){
初始化子集();
返回complexSubsets.get(this);
}
私有静态void initSubsets(){
if(complexSubsets==null){
Map Map=新的EnumMap(StyleEnum.class);
map.put(无,集合.unmodifiableSet(EnumSet.of(
黑体字(斜体);
map.put(粗体,Collections.unmodifiableSet(EnumSet.of(
下划线);;
map.put(斜体,Collections.unmodifiableSet(EnumSet.of(
下划线);;
map.put(下划线,Collections.emptySet());
map.put(删除线,集合.unmodifiableSet(EnumSet.of(
无),;
map.put(B_和I,Collections.unmodifiableSet(EnumSet.of(
黑体字(斜体);
complexSubsets=Collections.unmodifiableMap(映射);
断言complexSubsets.keySet().containsAll(
EnumSet.allOf(StyleEnum.class)):
“并非所有值都定义了子集”;
}
}
}

我将放弃在实例字段中保留辅助集,而是将其实现为静态映射:

import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.EnumMap;
import java.util.EnumSet;

public enum StyleEnum {
    NONE(0, "none"),
    BOLD(100, "B"),
    ITALIC(250, "i"),
    UNDERLINE(350, "u"),
    STRIKETHROUGH(9, "b"),
    B_AND_I(99,"Emphase");

    private static Map<StyleEnum, Set<StyleEnum>> complexSubsets;

    private final int intProp;
    private final String strLabel;

    StyleEnum(int intProp, String strLabel) {
        this.intProp = intProp;
        this.strLabel = strLabel;
    }

    public Set<StyleEnum> getComplexSubset() {
        initSubsets();
        return complexSubsets.get(this);
    }

    private static void initSubsets() {
        if (complexSubsets == null) {
            Map<StyleEnum, Set<StyleEnum>> map = new EnumMap<>(StyleEnum.class);
            map.put(NONE, Collections.unmodifiableSet(EnumSet.of(
                BOLD, ITALIC)));
            map.put(BOLD, Collections.unmodifiableSet(EnumSet.of(
                UNDERLINE)));
            map.put(ITALIC, Collections.unmodifiableSet(EnumSet.of(
                UNDERLINE)));
            map.put(UNDERLINE, Collections.emptySet());
            map.put(STRIKETHROUGH, Collections.unmodifiableSet(EnumSet.of(
                NONE)));
            map.put(B_AND_I, Collections.unmodifiableSet(EnumSet.of(
                BOLD, ITALIC)));
            complexSubsets = Collections.unmodifiableMap(map);

            assert complexSubsets.keySet().containsAll(
                EnumSet.allOf(StyleEnum.class)) :
                "Not all values have subsets defined";
        }
    }
}
import java.util.Collections;
导入java.util.Map;
导入java.util.Set;
导入java.util.EnumMap;
导入java.util.EnumSet;
公共枚举样式枚举{
无(0,“无”),
粗体(100,“B”),
斜体(250,“i”),
下划线(350,“u”),
删除线(9,“b”),
B_和I(99,“强调”);
私有静态映射复合子集;
私人最终int intProp;
私有最终字符串标签;
StyleEnum(int intProp,字符串strLabel){
this.intProp=intProp;
this.strLabel=strLabel;
}
公共集getComplexSubset(){
初始化子集();
返回complexSubsets.get(this);
}
私有静态void initSubsets(){
if(complexSubsets==null){
Map Map=新的EnumMap(StyleEnum.class);
map.put(无,集合.unmodifiableSet(EnumSet.of(
黑体字(斜体);
map.put(粗体,Collections.unmodifiableSet(EnumSet.of(
下划线);;
map.put(斜体,Collections.unmodifiableSet(EnumSet.of(
下划线);;
map.put(下划线,Collections.emptySet());
map.put(删除线,集合.unmodifiableSet(EnumSet.of(
无),;
map.put(B_和I,Collections.unmodifiableSet(EnumSet.of(
黑体字(斜体);
complexSubsets=Collections.unmodifiableMap(映射);
断言complexSubsets.keySet().containsAll(
EnumSet.allOf(StyleEnum.class)):
“并非所有值都定义了子集”;
}
}
}

不应
e.complexComputedSubSet=EnumSet.copyOf(someComputedCollection)足够吗?您仍然需要删除
final
关键字,但这不会有什么坏处。顺便说一句,我认为
EnumSet.noneOf(StyleEnum.class)
应该等同于
新的EnumSet()你在找。JavaDoc声明:“创建具有指定元素类型的空枚举集。”-该方法名称非常不幸:)这是我真正的第一个尝试:
private EnumSet complexComputedSubSet=EnumSet.noneOf(StyleEnum.class)但这句可爱的话在这个可怕的轨迹中得到了解决:
原因是:java.lang.ClassCastException:class entity.StyleEnum不是枚举
`at java.util.EnumSet.Noeof(EnumSet.java:112)`
at entity.StyleEnum.(StyleEnum.java:22)
`at entity.StyleEnum.(StyleEnum.java:5)`所以我就放弃了它的使用。你答案上的注释是为了在字段级别处理
EnumSet.noneOf(StyleEnum.class)
。如果你不使用它(在初始化类之后),它就可以了。所以它不可能是我想要的简单的空构造函数。嗯,这很有趣,因为
EnumSet.of(NONE)
应该在一开始就在内部调用
noneOf(StyleEnum.class)
。我假设“字段级别”的意思是直接在字段声明中,对吗?您在静态块中尝试过吗?不应该
e.complexComputedSubSet=EnumSet.copyOf(someComputedCollection)足够吗?您仍然需要删除th
       for (StyleEnum e : EnumSet.allOf(StyleEnum.class)) {
           e.complexComputedSubSet = EnumSet.of(NONE);
       }
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.EnumMap;
import java.util.EnumSet;

public enum StyleEnum {
    NONE(0, "none"),
    BOLD(100, "B"),
    ITALIC(250, "i"),
    UNDERLINE(350, "u"),
    STRIKETHROUGH(9, "b"),
    B_AND_I(99,"Emphase");

    private static Map<StyleEnum, Set<StyleEnum>> complexSubsets;

    private final int intProp;
    private final String strLabel;

    StyleEnum(int intProp, String strLabel) {
        this.intProp = intProp;
        this.strLabel = strLabel;
    }

    public Set<StyleEnum> getComplexSubset() {
        initSubsets();
        return complexSubsets.get(this);
    }

    private static void initSubsets() {
        if (complexSubsets == null) {
            Map<StyleEnum, Set<StyleEnum>> map = new EnumMap<>(StyleEnum.class);
            map.put(NONE, Collections.unmodifiableSet(EnumSet.of(
                BOLD, ITALIC)));
            map.put(BOLD, Collections.unmodifiableSet(EnumSet.of(
                UNDERLINE)));
            map.put(ITALIC, Collections.unmodifiableSet(EnumSet.of(
                UNDERLINE)));
            map.put(UNDERLINE, Collections.emptySet());
            map.put(STRIKETHROUGH, Collections.unmodifiableSet(EnumSet.of(
                NONE)));
            map.put(B_AND_I, Collections.unmodifiableSet(EnumSet.of(
                BOLD, ITALIC)));
            complexSubsets = Collections.unmodifiableMap(map);

            assert complexSubsets.keySet().containsAll(
                EnumSet.allOf(StyleEnum.class)) :
                "Not all values have subsets defined";
        }
    }
}