2013-05-06 20 views
18

Helfen Sie mir, Generika zu verstehen. Sagen wir, ich habe zwei Aufzählungen als innere Klassen wie folgt:Java: Generische Methode für Enums

public class FoodConstants{ 

    public static enum Vegetable { 

    POTATO,BROCCOLI,SQUASH,CARROT; 

    } 

    public static enum Fruit { 

    APPLE,MANGO,BANANA,GUAVA; 

    } 

} 

Statt beide Aufzählungen eine Schnittstelle mit implementieren und haben die gleiche Methode zweimal zu implementieren, würde Ich mag eine Methode in der äußeren Klasse haben, der etwas tut, wie:

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

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

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

Allerdings kompiliert diese Methode nicht. Was ich versuche zu tun, ist herauszufinden, ob ein String-Wert der Name eines aufgezählten Wertes ist, in JEDER enum, ob es Gemüse, Obst, was nicht ist. Unabhängig davon, ob dies tatsächlich eine redundante Methode ist, was ist falsch an der, die ich versuche (wieder) zu schreiben?

Grundsätzlich würde Ich mag, dies zu tun: für Ihre Hilfe

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 

Dank. -Alex

Antwort

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

Das Original hat einige Probleme:

  1. Er akzeptiert eine Instanz des Enum anstelle der Klasse, die die Aufzählungs , die Ihre Frage suggeriert die Sie verwenden möchten.
  2. Der Typparameter wird nicht verwendet.
  3. Es gibt die Eingabe anstelle des Instanznamens zurück. Vielleicht wäre die Rückgabe der Instanz nützlicher - eine Version ohne Berücksichtigung der Groß- und Kleinschreibung von Enum.valueOf(String).
  4. Es ruft eine statische Methode für eine Instanz auf, so dass Sie iterieren können. EnumSet macht alle reflektierenden Sachen für Sie.
+6

Oh, und clazz.getEnumConstants() würde anstelle von EnumSet.allOf (clazz) arbeiten. Es ist wahrscheinlich etwas effizienter, wenn man bedenkt, dass EnumSet.allOf wahrscheinlich in Bezug darauf implementiert wurde, aber dann, vielleicht nicht. –

+0

@SebastianRedl, ungerade. Ich dachte, das war nicht in 1.5, aber anscheinend ist es. –

+5

@SebastianRedl: Tatsächlich ist 'EnumSet.allOf()' effizienter als '.getEnumConstants()', weil '.getEnumConstants()' eine Kopie des internen Arrays von Konstanten erstellen muss (da es ein Array zurückgibt und dort ist nicht in der Lage zu verhindern, dass ein Array geändert wird), während "EnumSet" interne Implementierungsdetails verwenden kann, um direkt über das interne Array zu iterieren. – newacct