最近我一直在尝试做一个相对论的能量计算器。我用List<ComponentType>
表示任何在ComponentType.ELECTRON
,ComponentType.PROTON
和ComponentType.NEUTRON
上构建的粒子,其中ComponentType
是包含质量的enum
。
后来我想做一个ParticleFactory
类,它对应于GUI下拉列表中的基本粒子列表。就像:ParticleFactory(Hydrogen)
会给我一个包含{ComponentType.ELECTRON, ComponentType.PROTON}
列表的粒子对象。这将使修改变得容易,因为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
? 最佳答案
我认为您需要以下设计:
名为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数组,因为它们会给其他开发人员和您自己带来很多负担,我更喜欢对象。