2009-07-29 22 views
5

W całym naszym projekcie mamy tego rodzaju wyliczenia. Działają dobrze, ale nie jesteśmy do końca pewni.czy moje wyliczenie jest poprawne?

Specjalnie z metodą getDocumentType (String).

Czy istnieje sposób na uniknięcie iteracji na wszystkich polach Enums?

public enum DocumentType { 

    UNKNOWN("Unknown"), 
    ANY("Any"), 
    ASSET(Asset.class.getSimpleName()), 
    MEDIA(Media.class.getSimpleName()), 
    MEDIA35MM(Media.class.getSimpleName() + " 35mm"); 


    private String label; 

    private DocumentType(String label) { 
     this.label = label; 
    } 

    public String getLabel() { 
     return label; 
    } 

    public static DocumentType getDocumentType(String label){ 
     for(DocumentType documentType : DocumentType.values()){ 
      if(documentType.getLabel().equals(label)){ 
       return documentType; 
      } 
     } 
     return UNKNOWN; 
    } 
} 

Edytuj: Sprawdź odpowiedź newacct. Ona też jest w porządku.

+1

To kuszące, aby zapisać mapie statycznej etykiet do wyliczenia wystąpień, ale denerwująco, Java nie pozwala odwoływać się do pola statycznego od konstruktora enum jest. – skaffman

+1

Zastanawiam się, dlaczego używasz Asset.class.getSimpleName() zamiast pisać "Zasób"? Czy planujesz zmienić nazwę przez refaktoryzację? – akarnokd

+1

Czy używanie tekstów klas zamiast ciągów zawsze jest dobrą praktyką? – skaffman

Odpowiedz

5

Będziesz musiał zrobić to gdzieś, ze względu na ograniczenia w pisaniu wyrażeń. W idealnym świecie wypełnisz statyczną mapę z poziomu konstruktora DocumentType, ale to niedozwolone.

Najlepszym mogę zaproponować jest wykonywanie iteracji raz w statycznego inicjatora i przechowywanie stałe teksty w tabeli odnośników:

public enum DocumentType { 

    .... existing enum stuff here 

    private static final Map<String, DocumentType> typesByLabel = new HashMap<String, DocumentType>(); 
    static { 
     for(DocumentType documentType : DocumentType.values()){ 
      typesByLabel.put(documentType.label, documentType); 
     } 
    } 

    public static DocumentType getDocumentType(String label){ 
     if (typesByLabel.containsKey(label)) { 
      return typesByLabel.get(label); 
     } else { 
      return UNKNOWN; 
     } 
    } 
} 

Przynajmniej nie będzie robić iteracji za każdym razem, chociaż wątpię, że zauważysz znaczącą poprawę wydajności.

+0

+1 Właśnie o czym myślałem, pokonałeś mnie do it though =) – mikek

+1

Właśnie spędziłem 10 minut lub tak krzycząc na kompilator – skaffman

+0

Jeśli w enum jest 100 elementów (lub nawet tysięcy), to może to być poprawa wydajności ...może, zwłaszcza jeśli bardzo ich szukasz. – aperkins

1

Z tego, co wiem (za to, co warto), jest to najlepszy sposób robienia tego, co chcesz.

Tak właśnie zrobiłbym to co najmniej.

Jeśli liczba enum rośnie znacząco (kilkaset tysięcy) - może warto dodać Map ing z Strings do enums zrobić rozglądać się trochę szybciej. Ale jeśli masz małą liczbę eunums, może to być przesada.

1

Wygląda dobrze dla mnie.

Pozostawiłbym iterację taką, jaka jest. Na pewno można dodać implementację "etykiety", "DocumentType"> do klasy wyliczeniowej i wykonać wyszukiwanie, ale nie zwiększy to znacząco wydajności.

1

Jeśli ciągi są znane w czasie kompilacji, a jeśli są one ważne identyfikatory, można po prostu użyć ich jako nazw bezpośrednio teksty stałe:

public enum DocumentType { Unknown, Any, Asset, Media, Media35mm } 

a następnie dostać go .valueOf(). Na przykład:

String label = "Asset"; 
DocumentType doctype; 
try { 
    doctype = DocumentType.valueOf(label); 
} catch (IllegalArgumentException e) { 
    doctype = DocumentType.Unknown; 
} 
+0

Kolega przybył z tym samym rozwiązaniem. Jest to w porządku przez większość czasu, nie w naszym dokładnym przypadku, ale dla następnej iteracji sprawdzimy, czy naprawdę nie mamy identyfikatora i etykiety. –