编码提示 – 交集类型和java枚举

交集类型允许您(有点排序)执行具有inheritance层次结构的枚举。 您不能inheritance实现,但可以将其委托给辅助类。

enum Foo1 implements Bar {} enum Foo2 implements Bar {} class HelperClass { static <T extends Enum & Bar> void fooBar(T the enum) {} } 

当您有许多实现某种模式的不同枚举时,这很有用。 例如,许多具有父子关系的枚举对。

 enum PrimaryColor {Red, Green, Blue;} enum PastelColor {Pink, HotPink, Rockmelon, SkyBlue, BabyBlue;} enum TransportMedium {Land, Sea, Air;} enum Vehicle {Car, Truck, BigBoat, LittleBoat, JetFighter, HotAirBaloon;} 

您可以编写通用方法,说“好的,给定一个枚举值,该枚举值是某些其他枚举值的父级,子类型的所有可能子枚举中有多少百分比将此特定父值作为其父级?”,并且全部使用类型安全,没有铸造完成。 (例如:“Sea”占所有可能车辆的33%,而“Green”占所有可能车辆的20%)。

代码看起来像这样。 特别注意“叶子”类本身非常整洁 – 但是generics类的声明非常难看。 没关系:你只写一次。 一旦通用类存在,那么使用它们很容易。

下面的助手类只有一些静态方法。 其他方式包括

  • 提供一个返回单例的实例,但是根据父/子进行输入
  • 为每个paren / child返回一个实例,适当地键入,并在每个父enum中包含一个实例

使用第二个选项,“children”对象实际上将位于帮助程序中,因此减少了枚举中所需的代码量。 他们都会实例化一个帮助者,并将任何困难的事情委托给他们。

 import java.util.EnumSet; import javax.swing.JComponent; public class zz extends JComponent { public static void main(String[] args) { System.out.println(PrimaryColor.Green + " " + ParentUtil.pctOf(PrimaryColor.Green) + "%"); System.out.println(TransportMedium.Air + " " + ParentUtil.pctOf(TransportMedium.Air) + "%"); } } interface Parent<P extends Enum

& Parent

, C extends Enum & Child

> { Class getChildClass(); EnumSet getChildren(); } interface Child<P extends Enum

& Parent

, C extends Enum & Child

> { Class

getParentClass(); P getParent(); } enum PrimaryColor implements Parent { Red, Green, Blue; private EnumSet children; public Class getChildClass() { return PastelColor.class; } public EnumSet getChildren() { if(children == null) children=ParentUtil.loadChildrenOf(this); return children; } } enum PastelColor implements Child { Pink(PrimaryColor.Red), HotPink(PrimaryColor.Red), // Rockmelon(PrimaryColor.Green), // SkyBlue(PrimaryColor.Blue), BabyBlue(PrimaryColor.Blue); final PrimaryColor parent; private PastelColor(PrimaryColor parent) { this.parent = parent; } public Class getParentClass() { return PrimaryColor.class; } public PrimaryColor getParent() { return parent; } } enum TransportMedium implements Parent { Land, Sea, Air; private EnumSet children; public Class getChildClass() { return Vehicle.class; } public EnumSet getChildren() { if(children == null) children=ParentUtil.loadChildrenOf(this); return children; } } enum Vehicle implements Child { Car(TransportMedium.Land), Truck(TransportMedium.Land), // BigBoat(TransportMedium.Sea), LittleBoat(TransportMedium.Sea), // JetFighter(TransportMedium.Air), HotAirBaloon(TransportMedium.Air); private final TransportMedium parent; private Vehicle(TransportMedium parent) { this.parent = parent; } public Class getParentClass() { return TransportMedium.class; } public TransportMedium getParent() { return parent; } } class ParentUtil { private ParentUtil(){} static <P extends Enum

& Parent

, C extends Enum & Child

> // float pctOf(P parent) { return (float) parent.getChildren().size() / // (float) EnumSet.allOf(parent.getChildClass()).size() // * 100f; } public static <P extends Enum

& Parent

, C extends Enum & Child

> // EnumSet loadChildrenOf(P p) { EnumSet cc = EnumSet.noneOf(p.getChildClass()); for(C c: EnumSet.allOf(p.getChildClass())) { if(c.getParent() == p) { cc.add(c); } } return cc; } }

您可以使用Commons Enum实现:

http://commons.apache.org/lang/api-2.3/org/apache/commons/lang/enums/Enum.html

这允许您创建可以进行子类化的Enum。

这更简单,它能做你想要的吗?

 import java.util.*; interface Tree{ Tree parent(); Set children(); } enum PrimaryColor implements Tree { Red,Green,Blue; @Override public Tree parent() { return null; } @Override public Set children() { return Collections.unmodifiableSet(children); } final Set children=new LinkedHashSet(); } enum PastelColor implements Tree { Pink(PrimaryColor.Red),HotPink(PrimaryColor.Red),Rockmelon(PrimaryColor.Green),SkyBlue(PrimaryColor.Blue),BabyBlue(PrimaryColor.Blue); PastelColor(final PrimaryColor primaryColor) { this.primaryColor=primaryColor; if (primaryColor!=null) primaryColor.children.add(this); } @Override public Tree parent() { return primaryColor; } @Override public Set children() { return Collections.emptySet(); } double percent() { return primaryColor.children().size()*100./EnumSet.allOf(super.getClass()).size(); } private final PrimaryColor primaryColor; } public class Main{ static double percent(final Tree tree) { final Tree parent=tree.parent(); if (tree instanceof Enum) { return parent.children().size()*100./((Enum)tree).getClass().getEnumConstants().length; } else throw new RuntimeException("strange tree!"); } public static void main(String[] args) { System.out.println("one way"); for(PastelColor pastelColor:PastelColor.values()) System.out.println(pastelColor+" "+pastelColor.percent()); System.out.println("another way"); for(PastelColor pastelColor:PastelColor.values()) System.out.println(pastelColor+" "+percent(pastelColor)); } }