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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17646335/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-01 14:31:44  来源:igfitidea点击:

Combining enums and using getter to return a specified enum

javaenums

提问by dalawh

Let's say I have 2 different sets of enums: fruits and vegetables.

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

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

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

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

I display all this in a JComboBox. After someone selects something, I want to use a getter method to get back the Enum.

我在 JComboBox 中显示所有这些。有人选择了一些东西后,我想使用 getter 方法来取回 Enum。

For a single enum, I would do something like:

对于单个枚举,我会执行以下操作:

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

Any ideas what the return type is? I tried using Enum instead of Fruits. When I do that, I don't seem to have access to the getName() methods.

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

回答by husayt

Here is another demonstration of what you're looking for. The difference between this and previous solutions is that this one is more generic and reusable pattern. This in fact goes beyond the original problem, to show some other benefits of this approach. So you might just comment the bits you don't need. I also attach a unit test to demonstrate the behaviour.

这是您正在寻找的另一个演示。这个和以前的解决方案之间的区别在于,这是一个更通用和可重用的模式。这实际上超出了最初的问题,展示了这种方法的其他一些好处。所以你可能只是评论你不需要的位。我还附上了一个单元测试来演示这种行为。

So basically to look for name Appleor APPLEin one of these enums just write:

所以基本上要查找名称AppleAPPLE在这些枚举之一中只写:

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

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

FruitVeg<>is an interface, which allows to also tap inside of Enum, this interface allows to do some very interesting things with enums below. Here are just some of the things you could do with that:

FruitVeg<>是一个接口,它也允许在枚举内部点击,这个接口允许用下面的枚举做一些非常有趣的事情。以下是您可以用它做的一些事情:

  • Enum.valueOf(fvg.getDeclaringClass(), fvg.name()): returns enum Valuee.g. APPLE

  • fvg.getRaw(): returns enum Valuee.g. APPLE

  • fvg.name(): returns enum's String Namee.g. APPLE

  • fvg.getFriendlyName(): e.g. Apple

  • fvg.getDeclaringClass(): returnsClass<Enum<?>>e.g. class ox.dummy.dummyTest$Fruits

  • fvg.getClass(): class ox.dummy.dummyTest$FruitsreturnsClass<?>

  • EnumSet.allOf(fvg.getDeclaringClass())): e.g. [APPLE, PEAR]

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

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

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

  • fvg.getFriendlyName():例如苹果

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

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

  • EnumSet.allOf(fvg.getDeclaringClass())):例如[苹果,梨]

Here is code

这是代码

   @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;
}

回答by Ashish Aggarwal

Option 1.
Create one method that returns Enum

选项 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;
}

and to get the name of enum you can use this method

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

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;
}

Option 2.
You can combine 2 enum as

选项 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()
    ... 
}

回答by William Morrison

Pass in the Enums themselves as values. Then use getSelectedItemto retrieve the selected object, and do a test to see what type the object is.

将枚举本身作为值传递。然后使用getSelectedItem来检索选中的对象,并进行测试以查看该对象是什么类型。

Make the return type of your method an Object, not an enum of a specific type. This would fix your problem.

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

However, I think your approach is wrong. If I wanted fruits and vegetables displayed in a list and broken into categories, I'd create an object to do so, and an enum to represent type of food like so:

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

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);

And only add Fooditems to your JComboBox. Return Fooditems when a selection is made, and test for food type using the FoodTypeenum.

并且只将Food项目添加到您的 JComboBox。Food做出选择时返回项目,并使用FoodType枚举测试食物类型。

回答by Java Devil

You could use Objectinstead of explicitly using Fruitor Vegetables

您可以使用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;
}

Downside of this however is that you will then have to compare and cast the result to what you want

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

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

回答by Steve P.

It sounds like what you're looking for is the ability to apply inheritance to enums, but this is not possible in java, as enumsimplicity extend java.lang.Enumand java does not support multiple inheritance.

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

Nonetheless, I think that using "nested enums" could solve your problem. By nested, I mean implementing an interface to get around the multiple inheritance issue. There are a few different approaches in the answers in the link, I assume one of them will suffice.

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