2013-05-06 10 views
18

Pomóż mi zrozumieć leki generyczne. Że mam dwa teksty stałe jako klas wewnętrznych tak:Java: Ogólna metoda dla Enums

public class FoodConstants{ 

    public static enum Vegetable { 

    POTATO,BROCCOLI,SQUASH,CARROT; 

    } 

    public static enum Fruit { 

    APPLE,MANGO,BANANA,GUAVA; 

    } 

} 

zamiast oba teksty stałe implementować interfejs i trzeba zaimplementować ten sam sposób dwa razy, chciałbym mieć metodę w zewnętrznej klasy, która robi coś na przykład:

public <e> String getEnumString<Enum<?> e, String s){ 

for(Enum en: e.values()){ 

    if(en.name().equalsIgnoreCase(s)){ 
    return s; 
} 
} 
return null; 
} 

Jednak ta metoda nie jest kompilowana. Próbuję się dowiedzieć, czy wartość ciągu jest nazwą wyliczonej wartości, w KAŻDYM wyliczeniu, czy to warzyw, owoców, a co nie. Bez względu na to, czy jest to w rzeczywistości metoda nadmiarowa, co jest nie tak z tym, które próbuję (ponownie) napisać?

Zasadniczo chciałbym to zrobić:

public class FoodConstants{ 

     public static enum Vegetable { 

     POTATO,BROCCOLI,SQUASH,CARROT; 

     } 

     public static enum Fruit { 

     APPLE,MANGO,BANANA,GUAVA; 

     } 


     public <e> String getEnumString<Enum<?> e, String s){ 

      for(Enum en: e.values()){ 

       if(en.name().equalsIgnoreCase(s)){ 

      return s; 
      } 
     } 
    return null; 
     } 

    } //end of code 

Dzięki za pomoc. -Alex

Odpowiedz

46
public static <E extends Enum<E>> 
String getEnumString(Class<E> clazz, String s){ 
    for(E en : EnumSet.allOf(clazz)){ 
    if(en.name().equalsIgnoreCase(s)){ 
     return en.name(); 
    } 
    } 
    return null; 
} 

Oryginalny ma kilka problemów:

  1. akceptuje instancji enum zamiast klasę reprezentującą enum której Twoje pytanie sugeruje, którego chcesz użyć.
  2. Parametr typu nie jest używany.
  3. Zwraca dane wejściowe zamiast nazwy instancji. Może zwrócenie instancji byłoby bardziej użyteczne - niewrażliwa na wielkość liter wersja Enum.valueOf(String).
  4. Wywołuje metodę statyczną dla instancji, aby umożliwić iterację. EnumSet wykonuje dla Ciebie wszystkie elementy odblaskowe.
+6

Och, i clazz.getEnumConstants() będzie działać zamiast EnumSet.allOf (clazz). Prawdopodobnie jest nieco bardziej efektywny, biorąc pod uwagę, że EnumSet.allOf jest prawdopodobnie zaimplementowany pod tym względem, ale może nie. –

+0

@SebastianRedl, Odd. Myślałem, że to nie jest dostępne w 1.5, ale najwyraźniej tak jest. –

+5

@SebastianRedl: faktycznie, 'EnumSet.allOf()' jest bardziej wydajne niż '.getEnumConstants()', ponieważ '.getEnumConstants()' musi utworzyć kopię wewnętrznej tablicy stałych (ponieważ zwraca tablicę, a tam nie jest sposobem, aby zapobiec modyfikowaniu tablicy), podczas gdy 'EnumSet' może używać wewnętrznych szczegółów implementacji do bezpośredniego iterowania po wewnętrznej tablicy. – newacct

Powiązane problemy