结合枚举并使用getter返回指定的枚举

时间:2013-07-15 03:29:54

标签: java enums

假设我有2种不同的枚举:水果和蔬菜。

public static enum Fruits{
    APPLE ("Apple"),
    PEAR ("Pear");

    //constructor
    //getName()
    ... 
}
public static enum Vegetables{
    CARROT ("Carrot"),
    LETTUCE ("Lettuce");

    //constructor
    //getName()
    ...
}

我在JComboBox中显示所有这些。在某人选择了某些内容之后,我想使用getter方法来取回Enum。

对于单个枚举,我会做类似的事情:

public static Fruits getEnum(String name) {
  for(Fruits fruit: Fruits.values()) {
    if(name.equals(fruit.getName())) {
      return fruit;
    }
  }
  return null;
}

任何想法返回类型是什么?我尝试使用Enum而不是Fruits。当我这样做时,我似乎无法访问getName()方法。

5 个答案:

答案 0 :(得分:18)

这是您正在寻找的另一个示范。此解决方案与以前的解决方案之间的区别在于,此解决方案更通用且可重复使用。事实上这超出了原来的问题,显示了这种方法的一些其他好处。所以你可能只是评论你不需要的位。我还附上一个单元测试来证明行为。

所以基本上只需要在其中一个枚举中查找名称AppleAPPLE

FruitVeg<?> fvg = getEnum("APPLE", Fruits.class, Vegetables.class);

FruitVeg<>是一个界面,它允许点击Enum内部,这个界面允许用下面的枚举做一些非常有趣的事情。以下是您可以采取的一些措施:

  • Enum.valueOf(fvg.getDeclaringClass(), fvg.name())返回枚举值,例如 APPLE

  • fvg.getRaw()返回枚举值,例如 APPLE

  • fvg.name()返回枚举的字符串名称,例如的 APPLE

  • fvg.getFriendlyName():例如 Apple

  • fvg.getDeclaringClass()返回 Class<Enum<?>>,例如 class ox.dummy.dummyTest $ Fruits

  • fvg.getClass() class ox.dummy.dummyTest $ Fruits 返回 Class<?>

  • EnumSet.allOf(fvg.getDeclaringClass())):例如 [APPLE,PEAR]

这是代码

   @Test
public void doSimpleTest() throws Exception {

    FruitVeg<?> fvg = getEnum("APPLE", Fruits.class, Vegetables.class);
    log.info("{} : {} : {} : {} : {}", fvg.name(), fvg.getFriendlyName(), fvg.getClass(), fvg.getDeclaringClass(), EnumSet.allOf(fvg.getDeclaringClass()));
    log.info("get enum: {} ", Enum.valueOf(fvg.getDeclaringClass(), fvg.name()));

}


public interface FruitVeg<T extends Enum<T>> {
    String name();

    String getFriendlyName();

    Class<T> getDeclaringClass();

    T getRaw();

}

enum Fruits implements FruitVeg<Fruits> {
    APPLE("Apple"),
    PEAR("Pear");

    Fruits(String friendlyName) {
        this.friendlyName = friendlyName;
    }

    private final String friendlyName;

    @Override
    public String getFriendlyName() {
        return friendlyName;
    }
    @Override
    public Fruits getRaw() {
        return this;
    }
}


enum Vegetables implements FruitVeg<Vegetables> {
    CARROT("Carrot"),
    LETTUCE("Lettuce");

    Vegetables(String friendlyName) {
        this.friendlyName = friendlyName;
    }

    private final String friendlyName;

    @Override
    public String getFriendlyName() {
        return friendlyName;
    }

    @Override
    public Vegetables getRaw() {
        return this;
    }
}


public static FruitVeg<?> getEnum(String name, Class<? extends FruitVeg<?>>... fvgClasses) {
    for (Class<? extends FruitVeg<?>> fruitVegCLass : Arrays.asList(fvgClasses)) {
        for (FruitVeg<?> fvg : fruitVegCLass.getEnumConstants()) {
            if (name.equals(fvg.name()) || name.equals(fvg.getFriendlyName())) {
                return fvg;
            }
        }
    }
    return null;
}

答案 1 :(得分:3)

选项1.
创建一个返回Enum

的方法
public static Enum getEnum(String name) {
    Enum selectedEnum = null;
    for (Fruits fruit : Fruits.values()) {
        if (name.equals(fruit.getName())) {
            selectedEnum = fruit;
        }
    }

    for (Vegetables vegetables : Vegetables.values()) {
        if (name.equals(vegetables.getName())) {
            selectedEnum = vegetables;
        }
    }
    return selectedEnum;
}

并获取枚举的名称,您可以使用此方法

public static String getName(final Enum value) {
    String name = null;
    if (value instanceof Fruits) {
        name = ((Fruits) value).getName();
    } else if (value instanceof Vegetables) {
        name = ((Vegetables) value).getName();
    }
    return name;
}

选项2.
您可以将2枚枚举为

public static enum FruitsAndVegitables{
    APPLE ("Apple" , true),
    PEAR ("Pear", true),
    CARROT ("Carrot", false),
    LETTUCE ("Lettuce", false);

    private String name;
    private boolean isFurit;
    //constructor
    //getName()
    ... 
}

答案 2 :(得分:1)

将Enums本身作为值传递。然后使用getSelectedItem检索所选对象,并进行测试以查看对象的类型。

使方法的返回类型为Object,而不是特定类型的枚举。这可以解决您的问题。

但是,我认为你的方法是错误的。如果我想要将水果和蔬菜显示在列表中并分类,我会创建一个这样做的对象,以及一个代表食物类型的枚举:

public enum FoodType{FRUIT, VEGETABLE}
public class Food{
    FoodType type;
    String name;
    public Food(FoodType type, String name){
        this.type = type;
        this.name = name;
    }
    public String toString(){return this.name;}
}

//and then when you want to use it...
Food lettuce = new Food(FoodType.VEGETABLE, "Lettuce");
Food berry = new Food(FoodType.BERRY, "Berry");
comboBox.add(lettuces);
comboBox.add(berry);

仅向您的JComboBox添加Food个项目。在做出选择时返回Food项,并使用FoodType枚举测试食物类型。

答案 3 :(得分:0)

听起来你正在寻找的是将继承应用于enums的能力,但这在java中是不可能的,因为enums隐含扩展java.lang.Enum而java不支持多重继承。

尽管如此,我认为使用“ nested enums ”可以解决您的问题。通过嵌套,我的意思是实现一个接口来解决多重继承问题。在链接的答案中有几种不同的方法,我假设其中一种就足够了。

答案 4 :(得分:0)

您可以使用Object代替明确使用FruitVegetables

public static Object getEnum(String name) 
{    
    for(Fruits fruit: Fruits.values()) 
    {
        if(name.equals(fruit.getName())) 
        {
              return fruit;
        }
    }
    for(Vegetables vege: Vegetables.values()) 
    {
        if(name.equals(Vegetables.getName())) 
        {
              return vege;
        }
    }
  return null;
}

然而,这样做的缺点是,您必须比较并将结果转换为您想要的结果

Object o = getEnum("Carrot")
if(o instanceof Vegetable)
{
     Vegetable v = (Vegetable)o;
     v.getName();
}
//.. and again for fruit