2013-07-15 16 views
7

Załóżmy, że mam 2 różne zestawy wyrażeń: owoce i warzywa.Łączenie wyliczeń i używanie gettera w celu zwrócenia określonego wyliczenia

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

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

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

Wyświetlam to wszystko w JComboBox. Gdy ktoś coś wybierze, chcę użyć metody gettera, aby odzyskać Enum.

Dla pojedynczego wyliczenia, chciałbym zrobić coś takiego:

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

jakieś pomysły co typ zwracany jest? Próbowałem używać Enum zamiast Fruits. Kiedy to robię, wydaje się, że nie mam dostępu do metod getName().

Odpowiedz

0

To brzmi jak co szukasz jest możliwość zastosowania dziedziczenia do enums, ale nie jest to możliwe w Javie, jak enums implicity przedłużyć java.lang.Enum i java nie obsługuje wielokrotnego dziedziczenia.

Mimo to, myślę, że użycie "nested enums" może rozwiązać twój problem. Przez zagnieżdżenie rozumiem implementowanie interfejsu, aby obejść problem wielokrotnego dziedziczenia. Jest kilka różnych podejść w odpowiedziach w linku, zakładam, że jeden z nich wystarczy.

3

Wariant 1.
Tworzenie jedną metodę, która zwraca 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; 
} 

i uzyskać nazwę wyliczenia można użyć tej metody

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

Wariant 2.
Możesz połączyć 2 enum jako

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

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

Ponieważ nie chcą łączyć teksty stałe, chyba moja jedyna opcja to 1. – dalawh

+0

@dalawh Jeśli znalazłeś żadnej odpowiedzi pomocne dla ciebie. Następnie przekaż i zaakceptuj te odpowiedzi, aby w przyszłości były pomocne dla innych. Stwierdziłem, że zadałeś tyle pytań, ale nie akceptujesz żadnej odpowiedzi. Jeśli więc jakakolwiek odpowiedź rozwiąże Twój problem, zaakceptuj tę odpowiedź. –

+0

Więc nie ma sposobu na uzyskanie typu wyliczeniowego w ramach wyliczenia bez konieczności łączenia wyrażeń? – dalawh

1

Przepisz w Enums się wartościami. Następnie użyj getSelectedItem, aby pobrać wybrany obiekt, i wykonaj test, aby zobaczyć, jaki typ obiektu jest.

Wpisz typ zwracanej metody jako Obiekt, a nie wyliczenie określonego typu. To naprawi twój problem.

Uważam jednak, że Twoje podejście jest złe. Gdybym chciał owoce i warzywa wyświetlane na liście i podzielone na kategorie, chciałbym utworzyć obiekt, aby to zrobić, i enum do reprezentowania rodzaj żywności tak:

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

I tylko dodać Food elementy do JComboBox. Zwróć pozycje Food po dokonaniu selekcji i przetestuj rodzaj żywności za pomocą wyliczenia FoodType.

0

Można użyć Object zamiast jawnie przy użyciu Fruit lub Vegetables

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

minusem tego jest jednak, że będzie wtedy trzeba porównać i oddanych wynik co chcesz

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

Miałem nadzieję, że nie muszę porównywać i rzucać wyników. – dalawh

+0

Niestety, ta opcja oznacza, że ​​musiałbym utworzyć instrukcję if, else if dla każdego innego wyliczenia, a kopia kodu musiałaby znajdować się w każdym z nich. – dalawh

15

Tu to kolejna demonstracja tego, czego szukasz. Różnica między tymi i poprzednimi rozwiązaniami polega na tym, że ten jest bardziej ogólny i nadaje się do ponownego użycia. W rzeczywistości wykracza to poza pierwotny problem, aby pokazać inne zalety tego podejścia. Możesz więc po prostu skomentować bity, których nie potrzebujesz. Dołączam także test jednostkowy, aby zademonstrować zachowanie.

Więc w zasadzie szukać nazwy Apple lub APPLE w jednym z tych teksty stałe po prostu napisać:

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

FruitVeg<> jest interfejsem, który umożliwia także dotknąć wewnątrz Enum, interfejs ten pozwala zrobić kilka bardzo interesujące rzeczy z wyliczeniami poniżej. Oto tylko niektóre z rzeczy, które można zrobić z tym:

  • Enum.valueOf(fvg.getDeclaringClass(), fvg.name()): zwrotów enum Wartość przykład APPLE

  • fvg.getRaw(): powraca wyliczenia Wartość np APPLE

  • fvg.name(): powraca String name ENUM w np APPLE

  • fvg.getFriendlyName(): np. jabłko

  • fvg.getDeclaringClass(): powracaClass<Enum<?>> np klasy ox.dummy.dummyTest $ Owoce

  • fvg.getClass(): klasy ox.dummy.dummyTest $ OwocezwracaClass<?>

  • EnumSet.allOf(fvg.getDeclaringClass())) np: [jabłko, gruszka]

Oto kod

@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; 
} 
Powiązane problemy