如何制作包含枚举列表的枚举常量?

时间:2014-05-12 16:27:30

标签: java list enums

最近我一直试图制作一个相对论的能量计算器。我使用List<ComponentType>来表示ComponentType.ELECTRONComponentType.PROTONComponentType.NEUTRON上的任何粒子构建,其中ComponentType是包含质量的enum

后来我想创建一个ParticleFactory类,它对应于GUI下拉列表中的基本粒子列表。像:ParticleFactory(Hydrogen)会给我一个包含{ComponentType.ELECTRON, ComponentType.PROTON}列表的Particle对象。这将使修改变得容易,因为ParticleFactory和GUI将使用与基本粒子相同的enum

当我尝试实现它时出现问题。我知道它没有机会使用不正确的语法,但无论我做什么,我总是会遇到错误。

public enum GenericParticleType {

ELECTRON({"electron","e"}, new ArrayList<ComponentType>());

private final String[] names;
private final List<ComponentType> components;

GenericParticleType(String[] names, List<ComponentType> components) {
    this.names = names;
    this.components = components;
    }   
}

目标是让enum包含其他enums的列表。 :D有没有正确的方法呢?

是否有更好的方法可以做到这一点?常数HashMap

2 个答案:

答案 0 :(得分:1)

我认为你想要以下设计:

  • 名为GenericParticle
  • 的界面
  • 提供最基本实现的枚举。
  • 工厂/建筑工地,您可以随心所欲。

您可以使用以下代码实现此目的:

enum Component {
    ELECTRON, PROTON, NEUTRON;
}

interface GenericParticle {
    List<String> getNames();

    List<Component> getComponents();
}

enum BasicGenericParticle implements GenericParticle {
    ELECTRON(
            Arrays.asList("electron", "e"),
            Arrays.asList(Component.ELECTRON)
    ),
    HYDROGEN(
            Arrays.asList("hydrogen", "h"),
            Arrays.asList(Component.ELECTRON, Component.PROTON)
    )
    ;

    private final List<String> names;
    private final List<Component> components;

    private BasicGenericParticle(final List<String> names, final List<Component> components) {
        this.names = names;
        this.components = components;
    }

    @Override
    public List<String> getNames() {
        return new ArrayList<>(names);
    }

    @Override
    public List<Component> getComponents() {
        return new ArrayList<>(components);
    }
}

class GenericParticleBuilder {
    private List<String> names = new ArrayList<>();
    private List<Component> components = new ArrayList<>();

    public GenericParticleBuilder name(final String name) {
        names.add(name);
        return this;
    }

    public GenericParticleBuilder component(final Component component) {
        components.add(component);
        return this;
    }

    public GenericParticle build() {
        return new GenericParticleImpl(names, components);
    }

    private static class GenericParticleImpl implements GenericParticle {
        private List<String> names = new ArrayList<>();
        private List<Component> components = new ArrayList<>();

        public GenericParticleImpl(final List<String> names, final List<Component> components) {
            this.names = names;
            this.components = components;
        }

        @Override
        public List<String> getNames() {
            return new ArrayList<>(names);
        }

        @Override
        public List<Component> getComponents() {
            return new ArrayList<>(components);
        }
    }
}

用作:

    GenericParticle electron = BasicGenericParticle.ELECTRON;
    GenericParticle hydrogen = BasicGenericParticle.HYDROGEN;
    GenericParticle water = new GenericParticleBuilder()
            .name("water").name("h2o2")
            .component(/*components*/)
            .build();

您需要针对以下事实采取预防措施:

  • 除非客户当然自己实施GenericParticle,否则不应构造非法粒子,但为此你必须有文件证明他能做正确的事情。
  • 防御性复制的表现不是最好的,但你绝对希望字符串是不可变的。您可以考虑自己实现一个不可变列表(不应该更改列表中的元素),或者使用像guava(最好)这样的库提供的列表。我不会使用String数组,因为它们给其他开发人员和你自己带来了很多负担,我更喜欢对象。

答案 1 :(得分:0)

我认为没有问题:

public enum GenericParticleType {

    ELECTRON(new String[] { "electron", "e" },
            new ArrayList<GenericParticleType>()),

    MULTI_ELECTRON(new String[] { "me" }, Arrays.asList(ELECTRON, ELECTRON)),

    COMPOSITION(new String[] { "c" }, Arrays.asList(MULTI_ELECTRON, ELECTRON,
            ELECTRON));

    private final String[] names;

    private final List<GenericParticleType> components;

    GenericParticleType(String[] names, List<GenericParticleType> components) {
        this.names = names;
        this.components = components;
    }

    public String[] getNames() {
        return names;
    }

    public List<GenericParticleType> getComponents() {
        return components;
    }
}