Java 使用泛型类型Enum创建EnumMap

Java 使用泛型类型Enum创建EnumMap,java,Java,如果我有一堆类都包含一个Enum和EnumMap,我想为这些类创建一个超类 public interface ColorEnum { } class ColorMarbles extends Toy { enum MARBLE implements ColorEnum { BLUE, GREEN } EnumMap<MARBLE, String> names = new EnumMap<MARBLE, String>(MARBLE.cla

如果我有一堆类都包含一个Enum和EnumMap,我想为这些类创建一个超类

public interface ColorEnum {
}

class ColorMarbles extends Toy {
    enum MARBLE implements ColorEnum
        { BLUE, GREEN }
    EnumMap<MARBLE, String> names = new EnumMap<MARBLE, String>(MARBLE.class);
    //stuff
    // fields

    public void populate(ArrayList<String> designer) {
        int i = 0;
        for(MARBLE marble : MARBLE.values()) {
            marble.name = designer.get(i);
            i++;
        }
    }
}

class ColorBalloons extends Toy {
    enum BALLOON implements ColorEnum
        { YELLOW, RED }
    EnumMap<BALLOON, String> names = new EnumMap<BALLOON, String>(BALLOON.class);
    //stuff
    // fields

    public void populate(ArrayList<String> designer) {
        int i = 0;
        for(BALLOON balloon : BALLOON.values()) {
            balloon.name = designer.get(i);
            i++;
        }
    }
}
公共接口ColorEnum{
}
类彩色大理石玩具{
enum大理石实现了ColorEnum
{蓝色,绿色}
EnumMap名称=新的EnumMap(MARBLE.class);
//东西
//田地
公共空白填充(ArrayList设计器){
int i=0;
对于(大理石:MARBLE.values()){
marble.name=designer.get(i);
i++;
}
}
}
类彩色气球玩具{
枚举气球实现ColorEnum
{黄色,红色}
EnumMap名称=新的EnumMap(BALLOON.class);
//东西
//田地
公共空白填充(ArrayList设计器){
int i=0;
对于(引出序号:引出序号.values()){
balloon.name=designer.get(i);
i++;
}
}
}
如何创建一个超类,使其具有一个包含ColorEnum类型枚举的泛型EnumMap,如下所示

public abstract class Toy {
    EnumMap<ColorEnum, String> names;
}
公共抽象类玩具{
列举地图名称;
}
艾德:我意识到我的例子太模糊了。狗可能是个坏例子。我把它改成了更清晰的东西

我拥有的是一组类,它们的方法类似于填充EnumMap的populate。名称按预定义顺序排列。我不希望在每个类中定义populate,而是希望能够将它引入到Toy超类中,这样我就不必在每个新的类类型Toy中不断复制粘贴


希望这能解释更多我想要的东西。

我觉得你的设计太复杂了

使用枚举

如果不需要类继承,可以像处理顶级类一样直接使用枚举

public interface Animal {}

public enum Dog implements Animal {
    HUSKY("Husky"), LAB("Labrador");

    private final String name;

    Dog(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}
枚举可以像任何其他Java类一样声明字段、方法和实现接口。它们唯一的限制是它们的直接超类总是
java.lang.Enum
,不能扩展

但是,每个枚举常量都可以有自己的一组唯一数据传递给其构造函数。甚至可能每个常量都可以用其唯一的实现重写该枚举的公共方法

这是一个很好的教程,详细介绍了枚举的全部功能:


不带枚举

如果您需要一个实际的类继承来共享一些常用方法(例如从
Animal
超类),我仍然会放弃map方法,而是尝试一些更面向OOP的方法:

public class Animal {
}

public abstract class Dog extends Animal {

    public abstract String getName();

    public static class Husky extends Dog {
        @Override
        public String getName() {
            return "husky";
        }
    }

    public static class Lab extends Dog {
        @Override
        public String getName() {
            return "labrador";
        }
    }

}

我使用的一种机制是扩展一个泛型基类,该基类有一个泛型参数,允许您向上传递
Enum
详细信息

此示例为数据库表定义了一个基本
类:

public class Table<Column extends Enum<? extends Column>> {
  // Name of the table.
  protected final String tableName;
  // All of the columns in the table. This is actually an EnumSet so very efficient.
  protected final Set<Column> columns;

  /**
   * The base interface for all Column enums.
   */
  public interface Columns {
    // What type does it have in the database?
    public Type getType();
  }

  // Small list of database types.
  public enum Type {
    String, Number, Date;
  }

  public Table(String tableName,
               Set<Column> columns) {
    this.tableName = tableName;
    this.columns = columns;
  }

}

公共类表我不确定你想做什么。你能把它弄清楚一点吗?为什么不简单地使用HashMap呢?EnumMap只是enums的一个优化实现。我仍然看不清楚这里的意图。
populate()?为什么它们不能是静态的呢?您是否希望在运行时使用不同的值多次调用它们(从而更改名称)?对于大理石和气球,
designer
列表是否相同,这意味着蓝色大理石和黄色气球具有相同的名称,或者它们完全不相关?很抱歉问了这么多问题,但我仍然不明白为什么简单枚举方法在这里不起作用。:)@Natix I多次调用populate(),因此字段不能是静态的,就像在气球列表中一样,每个气球都有不同的设计器。@JustinYang,您真的需要枚举吗?难道你不能创建一个简单的集合,比如
List ballogs=new ArrayList()
并手动用气球对象填充所需名称?您还可以将
getName()
推送到接口。每个类中都有方法,它们执行完全相同的操作,并缩小所有类的大小,我希望创建一个可以容纳所有泛型方法的抽象超类。但要做到这一点,我需要访问EnumMap。也许我实际上并没有帮你解决问题,但这就是我从你的狗名示例中所能想到的。也许你应该把你的问题说得更具体一些,看看你想达到什么目的。@Natix谢谢你的回答,我意识到我的例子很糟糕。我对它进行了修改,希望它是clearerA聪明的模式,但我有点担心类型命名:
Columns
Table
中的嵌套接口,其中
Column
是在泛型Table类的范围内定义的类型变量。我会将声明更改为
类Table@Natix-我对命名很费劲,并且考虑了一种通用类型的大写字母的当前方法。无论如何,选择你喜欢的命名惯例。在我的环境中,我使用了十几个这样定义的表,
/
对我来说读起来最自然,没有混淆。显然,您看到了强类型检查的巨大好处,同时仍然能够只编写一次大多数锅炉板代码。
public class VersionTable extends Table<VersionTable.Column> {

  public enum Column implements Table.Columns {
    Version(Table.Type.String),
    ReleaseDate(Table.Type.Date);

    // Sadly all of this must be in ALL of your enums but most of the work can be pushed up to `Table`
    final Table.Type type;

    Column(Table.Type type) {
      this.type = type;
    }

    @Override
    public Type getType() {
      return type;
    }
  }

  public VersionTable() {
    super("Versions", EnumSet.allOf(Column.class));
  }
}