编码技巧-交集类型和java枚举

编码技巧-交集类型和java枚举,java,generics,enums,Java,Generics,Enums,交集类型允许您(有点类似)执行具有继承层次结构的枚举。您不能继承实现,但可以将其委托给帮助器类 enum Foo1 implements Bar {} enum Foo2 implements Bar {} class HelperClass { static <T extends Enum<T> & Bar> void fooBar(T the enum) {} } 您可以编写泛型方法,说“好的,给定一个枚举值,它是其他一些枚举值的父项,子类型的所有可

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

enum Foo1 implements Bar {}
enum Foo2 implements Bar {}

class HelperClass {
   static <T extends Enum<T> & Bar> void fooBar(T the enum) {}
}
您可以编写泛型方法,说“好的,给定一个枚举值,它是其他一些枚举值的父项,子类型的所有可能子枚举中,有多少百分比的子枚举将此特定父项值作为其父项?”,并使其都是类型安全的,并且在不强制转换的情况下完成。(例如:“Sea”占所有可能的车辆的33%,而“绿色”占所有可能的彩色颜料的20%)

代码如下所示。特别要注意的是,“叶”类本身非常整洁,但是泛型类的声明非常难看。没关系,你只写一次。一旦有了泛型类,那么使用它们就很容易了

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

  • 提供一个返回 singleton,但根据 父母/子女
  • 返回实例 对于每个paren/子级,键入 适当地,包括一个 每个父枚举
使用第二个选项,“children”对象实际上将位于helper内部,因此减少了枚举中所需的代码量。他们都会实例化一个助手,并委派任何困难的任务

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<P> & Parent<P, C>, C extends Enum<C> & Child<P, C>> {
    Class<C> getChildClass();

    EnumSet<C> getChildren();
}

interface Child<P extends Enum<P> & Parent<P, C>, C extends Enum<C> & Child<P, C>> {
    Class<P> getParentClass();

    P getParent();
}

enum PrimaryColor implements Parent<PrimaryColor, PastelColor> {
    Red, Green, Blue;

    private EnumSet<PastelColor>    children;

    public Class<PastelColor> getChildClass() {
        return PastelColor.class;
    }

    public EnumSet<PastelColor> getChildren() {
        if(children == null) children=ParentUtil.loadChildrenOf(this);
        return children;
    }
}

enum PastelColor implements Child<PrimaryColor, PastelColor> {
    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<PrimaryColor> getParentClass() {
        return PrimaryColor.class;
    }

    public PrimaryColor getParent() {
        return parent;
    }
}

enum TransportMedium implements Parent<TransportMedium, Vehicle> {
    Land, Sea, Air;

    private EnumSet<Vehicle>    children;

    public Class<Vehicle> getChildClass() {
        return Vehicle.class;
    }

    public EnumSet<Vehicle> getChildren() {
        if(children == null) children=ParentUtil.loadChildrenOf(this);
        return children;
    }
}

enum Vehicle implements Child<TransportMedium, Vehicle> {
    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<TransportMedium> getParentClass() {
        return TransportMedium.class;
    }

    public TransportMedium getParent() {
        return parent;
    }
}

class ParentUtil {
    private ParentUtil(){}
    static <P extends Enum<P> & Parent<P, C>, C extends Enum<C> & Child<P, C>> //
    float pctOf(P parent) {
        return (float) parent.getChildren().size() / //
                (float) EnumSet.allOf(parent.getChildClass()).size() //
                * 100f;
    }
    public static <P extends Enum<P> & Parent<P, C>, C extends Enum<C> & Child<P, C>> //
    EnumSet<C> loadChildrenOf(P p) {
        EnumSet<C> cc = EnumSet.noneOf(p.getChildClass());
        for(C c: EnumSet.allOf(p.getChildClass())) {
            if(c.getParent() == p) {
                cc.add(c);
            }
        }
        return cc;
    }
}
import java.util.EnumSet;
导入javax.swing.JComponent;
公共类zz扩展了JComponent{
公共静态void main(字符串[]args){
System.out.println(PrimaryColor.Green+“”+ParentUtil.pctOf(PrimaryColor.Green)+“%”;
System.out.println(transportmedia.Air+“”+ParentUtil.pctOf(transportmedia.Air)+“%”;
}
}
接口父级{
类getChildClass();
EnumSet getChildren();
}
接口子级{
类

getParentClass(); P getParent(); } enum PrimaryColor实现父对象{ 红、绿、蓝; 私人儿童; 公共类getChildClass(){ 返回PastelColor.class; } 公共枚举集getChildren(){ 如果(children==null)children=ParentUtil.loadChildrenOf(this); 返回儿童; } } enum PastelColor实现子对象{ 粉色(原色.红色),热粉色(原色.红色)// 甜瓜(原色。绿色)// 天蓝色(PrimaryColor.Blue),婴儿蓝(PrimaryColor.Blue); 最终原色母体; private PastelColor(PrimaryColor父级){ this.parent=parent; } 公共类getParentClass(){ 返回PrimaryColor.class; } 公共PrimaryColor getParent(){ 返回父母; } } enum TransportMedium实现父{ 陆、海、空; 私人儿童; 公共类getChildClass(){ 返回车辆.class; } 公共枚举集getChildren(){ 如果(children==null)children=ParentUtil.loadChildrenOf(this); 返回儿童; } } 枚举车辆实现子对象{ 汽车(TransportMedium.Land),卡车(TransportMedium.Land)// 大船(TransportMedium.Sea),小艇(TransportMedium.Sea)// 喷气式战斗机(TransportMedium.Air)、热气球(TransportMedium.Air); 私人媒体母公司; 私家车(运输工具){ this.parent=parent; } 公共类getParentClass(){ 返回中档; } 公共交通媒体getParent(){ 返回父母; } } 类ParentUtil{ 私有ParentUtil(){} 静态// 浮动pctOf(P父级){ return(float)parent.getChildren().size()/// (float)EnumSet.allOf(parent.getChildClass()).size()// *100f; } 公共静态// 枚举集loadChildrenOf(P){ EnumSet cc=EnumSet.noneOf(p.getChildClass()); 对于(C:EnumSet.allOf(p.getChildClass())){ if(c.getParent()==p){ cc.添加(c); } } 返回cc; } }


您只需使用Commons Enum实现即可:


它允许您创建枚举,然后可以对其进行子类化。

这更简单,它能满足您的需要吗

import java.util.*;
interface Tree{
    Tree parent();
    Set<Tree> children();
}
enum PrimaryColor implements Tree {
    Red,Green,Blue;
    @Override public Tree parent() {
        return null;
    }
    @Override public Set<Tree> children() {
        return Collections.unmodifiableSet(children);
    }
    final Set<Tree> children=new LinkedHashSet<Tree>();
}
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<Tree> 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));
    }
}
import java.util.*;
接口树{
树父对象();
设置子项();
}
enum PrimaryColor实现树{
红、绿、蓝;
@重写公共树父级(){
返回null;
}
@重写公共集子项(){
返回集合。不可修改集合(子项);
}
最终设置子项=新LinkedHashSet();
}
enum PastelColor实现树{
粉红色(PrimaryColor.Red)、热粉红色(PrimaryColor.Red)、甜瓜(PrimaryColor.Green)、天蓝色(PrimaryColor.Blue)、婴儿蓝(PrimaryColor.Blue);
巴斯德色(最终原色原色){
this.primaryColor=primaryColor;
if(primaryColor!=null)primaryColor.children.add(this);
}
@重写公共树父级(){
返回原色;
}
@重写公共集子项(){
返回集合;
}
百分之二{
返回primaryColor.children().size()*100./EnumSet.allOf(super.getClass()).size();
}
私有最终原色原色;
}
公共班机{
静态双百分比(最终树){
final Tree parent=Tree.parent();
if(枚举的树实例){return parent.children().size()*100./((枚举)树).getClass().getEnumConstants().length;}
否则抛出新的RuntimeException(“奇怪的树!”);
}
公共静态void main(字符串[]args){
System.out.println(“单向”);
对于(PastelColor PastelColor:PastelColor.values())
System.out.println(pastelColor+“”+pastelColor.percent());
System.out.println(“另一种方式”);
用于(Pas)
import java.util.*;
interface Tree{
    Tree parent();
    Set<Tree> children();
}
enum PrimaryColor implements Tree {
    Red,Green,Blue;
    @Override public Tree parent() {
        return null;
    }
    @Override public Set<Tree> children() {
        return Collections.unmodifiableSet(children);
    }
    final Set<Tree> children=new LinkedHashSet<Tree>();
}
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<Tree> 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));
    }
}