在Java中使用嵌套枚举类型
我心目中有一个涉及嵌套枚举的数据结构,因此我可以执行以下操作:在Java中使用嵌套枚举类型,java,enums,nested-class,Java,Enums,Nested Class,我心目中有一个涉及嵌套枚举的数据结构,因此我可以执行以下操作: Drink.COFFEE.getGroupName(); Drink.COFFEE.COLUMBIAN.getLabel(); 如果有方法声明: someMethod(Drink type) someOtherMethod(DrinkTypeInterface type) 然后我可以(恰当地)说: 这就是我想到的: public enum Drink { COFFEE("Coffee"); private S
Drink.COFFEE.getGroupName();
Drink.COFFEE.COLUMBIAN.getLabel();
如果有方法声明:
someMethod(Drink type)
someOtherMethod(DrinkTypeInterface type)
然后我可以(恰当地)说:
这就是我想到的:
public enum Drink {
COFFEE("Coffee");
private String groupName;
private Drink(String groupName) {
this.groupName = groupName;
}
public enum Coffee implements DrinkTypeInterface {
COLUMBIAN("Columbian Blend"),
ETHIOPIAN("Ethiopian Blend");
private String label;
private Coffee(String label) {
this.label = label;
}
public String getLabel() {
return this.label;
}
}
String getGroupName() {
return this.groupName;
}
}
以及界面:
public interface DrinkTypeInterface {
public String getLabel();
}
我想我只是想弄清楚用Java做这类事情的最好方法是什么,或者如果我需要编写一组if语句来处理单个的Drink.values()。有什么帮助吗?根据建议,考虑使用收集不同类型的饮料
附录:作为一个具体的例子,下面的代码生成所示的输出
Coffee: Columbian Blend
Coffee: Ethiopian Blend
咖啡:哥伦比亚混合咖啡
咖啡:埃塞俄比亚混合咖啡
代码:
公共静态枚举DrinkType{
咖啡(“咖啡”)、茶(“茶”);
私有最终字符串displayName;
private DrinkType(最终字符串显示名称){
this.displayName=displayName;
}
公共字符串getDisplayName(){
返回显示名;
}
}
公众饮料{
哥伦比亚人(DrinkType.COFFEE,“哥伦比亚混合”),
埃塞俄比亚(DrinkType.COFFEE,“埃塞俄比亚混合”),
薄荷茶(DrinkType.TEA,“薄荷”),
草药茶(DrinkType.TEA,“草药”),
格雷伯爵(DrinkType.TEA,“格雷伯爵”);
公共静态咖啡=EnumSet.of(哥伦比亚,埃塞俄比亚);
公共静态设置茶=枚举设置范围(薄荷茶、伯爵茶);
私有字符串组名;
私人串饮水机;
私人饮料(DrinkType类型,字符串drinkName){
this.groupName=type.getDisplayName();
this.drinkName=drinkName;
}
公共字符串getGroupName(){
返回this.groupName;
}
公共字符串getDrinkName(){
回饮;
}
}
公共静态void main(字符串…参数){
用于(饮料d:饮料。咖啡){
System.out.println(d.getGroupName()+“:”+d.getDrinkName());
}
}
首先,您给出的示例代码在某种程度上违反了“demeter定律”——因为COLUMBIAN实例字段仅用于检索标签。同样,在这种结构下,COLUMBIAN必须是COFFEE enum的一个例子,但我不认为这是你真正想要的
someMethod(Drink type)
someOtherMethod(DrinkTypeInterface type)
someMethod(Drink.COFFEE)
someOtherMethod(Drink.COFFEE.COLUMBIAN)
我从您的示例中收集到的是,您希望有一个枚举,其中包含实际饮料的“组类型”,然后每个枚举都有特定类型饮料的单独值。你的例子提供了咖啡,但茶也同样有效
问题在于如何放置枚举。正如我之前所说的,你必须把COLUMBIAN作为咖啡计数的一个例子,但这并不是构造这个的最好方法
问题是你有饮料,然后是咖啡/茶,然后是它们各自的类型。
但是,如果你想一想,虽然赫尔巴特茶是一种茶,但它也是一种饮料——因此它不属于茶的简单例子
但是,如果将饮料类型本身设置为枚举,则可以得到所需的内容,结构也会变得更清晰。由于接口和委托的力量,饮料类型和饮料枚举都可以以相同的方式处理,如下示例程序所示:
public final class DrinkEnumExample {
public interface DrinkTypeInterface {
String getDisplayableType();
}
public static enum DrinkType implements DrinkTypeInterface {
COFFEE("Coffee"), TEA("Tea");
private final String type;
private DrinkType(final String type) {
this.type = type;
}
public String getDisplayableType() {
return type;
}
}
public static enum Drink implements DrinkTypeInterface {
COLUMBIAN("Columbian Blend", DrinkType.COFFEE),
ETHIOPIAN("Ethiopian Blend", DrinkType.COFFEE),
MINT_TEA("Mint", DrinkType.TEA),
HERBAL_TEA("Herbal", DrinkType.TEA),
EARL_GREY("Earl Grey", DrinkType.TEA);
private final String label;
private final DrinkType type;
private Drink(String label, DrinkType type) {
this.label = label;
this.type = type;
}
public String getDisplayableType() {
return type.getDisplayableType();
}
public String getLabel() {
return label;
}
}
public DrinkEnumExample() {
super();
}
public static void main(String[] args) {
System.out.println("All drink types");
for (DrinkType type : DrinkType.values()) {
displayType(type);
System.out.println();
}
System.out.println("All drinks");
for (Drink drink : Drink.values()) {
displayDrink(drink);
System.out.println();
}
}
private static void displayDrink(Drink drink) {
displayType(drink);
System.out.print(" - ");
System.out.print(drink.getLabel());
}
private static void displayType(DrinkTypeInterface displayable) {
System.out.print(displayable.getDisplayableType());
}
}
该程序的输出如下:
所有饮料类型
咖啡
茶叶
所有饮料
哥伦比亚咖啡
埃塞俄比亚混合咖啡
薄荷茶
茶-草药
茶-格雷伯爵
那么,如果出于某种原因,你不想把所有的饮料都放在一个列表中,那么我不明白你想要什么。在这种情况下,如果您确实具有跨枚举的功能,请分别创建咖啡和茶(以及其他)枚举,并在两个(或更多)枚举上应用该接口。但是,我想你是想这样把他们分组。你可以这样做:
enum dogs {
boxer, collie;
}
enum cats {
siamese, tom
}
enum Animal {
cat(cats.tom), dog(dogs.boxer);
Animal(Enum e) {
this.e = e;
}
Object[] subValues() {
return e.getDeclaringClass().getEnumConstants();
}
final Enum e;
}
public class Main {
public static void main(String[] args) {
for (Animal animal : Animal.values()) {
System.out.print(animal);
for (Object o : animal.subValues())
System.out.print(" " + o);
System.out.println();
}
}
}
我最近很好奇,这是否能令人满意。这就是我最终得到的解决方案,我认为它的API也更接近于询问者最初想要的枚举树结构:
public interface Drink {
String groupName();
String label();
enum Coffee implements Drink {
COLUMBIAN("Columbian Blend"),
ETHIOPIAN("Ethiopian Blend");
private final String label;
Coffee(String label) {
this.label = label;
}
@Override
public String groupName() {
return "Coffee";
}
@Override
public String label() {
return label;
}
}
enum Tea implements Drink {
MINT("Mint"),
HERBAL("Herbal"),
EARL_GREY("Earl Grey");
private final String label;
Tea(String label) {
this.label = label;
}
@Override
public String groupName() {
return "Tea";
}
@Override
public String label() {
return label;
}
}
}
public static void main(String[] args) {
Drink choice = Drink.Tea.EARL_GREY;
System.out.println(choice.groupName()); // Tea
System.out.println(choice.label()); // Earl Grey
}
非常感谢您的详细回答!这足以让我知道我想做什么。为了澄清你最后说的话,基本上现在我有(另一位作者的作品)其中的一些,例如茶、咖啡。。。枚举。我希望能够将枚举类型本身视为一个类型,因此,例如,我可以有一个列表,并说类似于for(Drink-Drink:List){dosomething}。再次感谢!另外,在我的例子中,有一些方法,例如咖啡水平的方法,还有一些方法,例如哥伦比亚水平的方法。这就是为什么我没有尝试让它们都实现一个公共接口的原因。+1的。谢谢你的建议,我肯定为我澄清了一些关于枚举的问题。我想我对自己的目标不是很清楚,我努力想拿出一个有代表性的例子,而另一个回答成功地解密了我的意思,所以我接受了这个回答。但我非常感谢你的反馈,并投了你一票:)谢谢。实际上,我更喜欢@MetroidFan2002的类型标记方法,而不是String
constant(s)。我已经更新了我的示例以反映这个问题。这个问题要求嵌套枚举。您的示例仅显示了两个枚举。茶是一种计数,棺材是一种计数。但是,饮酒并不是一种统计。枚举嵌套意味着饮料本身不应该是接口,而应该是咖啡和茶的枚举。
public final class DrinkEnumExample {
public interface DrinkTypeInterface {
String getDisplayableType();
}
public static enum DrinkType implements DrinkTypeInterface {
COFFEE("Coffee"), TEA("Tea");
private final String type;
private DrinkType(final String type) {
this.type = type;
}
public String getDisplayableType() {
return type;
}
}
public static enum Drink implements DrinkTypeInterface {
COLUMBIAN("Columbian Blend", DrinkType.COFFEE),
ETHIOPIAN("Ethiopian Blend", DrinkType.COFFEE),
MINT_TEA("Mint", DrinkType.TEA),
HERBAL_TEA("Herbal", DrinkType.TEA),
EARL_GREY("Earl Grey", DrinkType.TEA);
private final String label;
private final DrinkType type;
private Drink(String label, DrinkType type) {
this.label = label;
this.type = type;
}
public String getDisplayableType() {
return type.getDisplayableType();
}
public String getLabel() {
return label;
}
}
public DrinkEnumExample() {
super();
}
public static void main(String[] args) {
System.out.println("All drink types");
for (DrinkType type : DrinkType.values()) {
displayType(type);
System.out.println();
}
System.out.println("All drinks");
for (Drink drink : Drink.values()) {
displayDrink(drink);
System.out.println();
}
}
private static void displayDrink(Drink drink) {
displayType(drink);
System.out.print(" - ");
System.out.print(drink.getLabel());
}
private static void displayType(DrinkTypeInterface displayable) {
System.out.print(displayable.getDisplayableType());
}
}
enum dogs {
boxer, collie;
}
enum cats {
siamese, tom
}
enum Animal {
cat(cats.tom), dog(dogs.boxer);
Animal(Enum e) {
this.e = e;
}
Object[] subValues() {
return e.getDeclaringClass().getEnumConstants();
}
final Enum e;
}
public class Main {
public static void main(String[] args) {
for (Animal animal : Animal.values()) {
System.out.print(animal);
for (Object o : animal.subValues())
System.out.print(" " + o);
System.out.println();
}
}
}
public interface Drink {
String groupName();
String label();
enum Coffee implements Drink {
COLUMBIAN("Columbian Blend"),
ETHIOPIAN("Ethiopian Blend");
private final String label;
Coffee(String label) {
this.label = label;
}
@Override
public String groupName() {
return "Coffee";
}
@Override
public String label() {
return label;
}
}
enum Tea implements Drink {
MINT("Mint"),
HERBAL("Herbal"),
EARL_GREY("Earl Grey");
private final String label;
Tea(String label) {
this.label = label;
}
@Override
public String groupName() {
return "Tea";
}
@Override
public String label() {
return label;
}
}
}
public static void main(String[] args) {
Drink choice = Drink.Tea.EARL_GREY;
System.out.println(choice.groupName()); // Tea
System.out.println(choice.label()); // Earl Grey
}