2016-07-23 10 views
0

Angenommen ich etwas wie das folgende tun:Wie kann ich ein EnumSet von generischen Varargs konstruieren?

public static <V> Set<V> setOf(V... elem) 
{ 
    Set<V> set = null; 
    if (elem[0] instanceof Enum) 
     set = Sets.newEnumSet(elem, elem[0].getClass()); OR 
     set = EnumSet.<V>noneOf(elem[0].getClass()); 
    return set; 
} 

Weder von diesen oder mehrere andere Varianten scheinen zu arbeiten. Kann mir jemand erklären, was vor sich geht? Ich habe How do I get the type object of a genericized Enum? und einige andere ähnliche Fragen angeschaut, aber ich kann immer noch nicht funktionieren.

Antwort

1

Zuerst müssen Sie sicherstellen, dass der Typ V auf einen Aufzählungstyp beschränkt ist; Sie können dies tun, indem Sie angeben, dass Vextends Enum<V> muss.

Dann müssen Sie die Class des Aufzählungstyps bereitstellen. Aufgrund des Löschens von Typen können Sie es zur Laufzeit nicht ableiten. Dies ist erforderlich, da Sie zum Erstellen einer neuen leeren EnumSet den Typ der Elemente angeben müssen.

Schließlich haben Sie mehrere Möglichkeiten, um das Set zu erstellen, aber die einfachste könnte die Stream-API zu verwenden sein:

@SafeVarargs 
public static <V extends Enum<V>> Set<V> setOf(Class<V> enumClass, V... elem) { 
    return Arrays.stream(elem).collect(Collectors.toCollection(() -> EnumSet.noneOf(enumClass))); 
} 

Beachten Sie, wenn Sie garantieren können, dass es mindestens ein Element sein wird, könnten Sie Verwenden Sie EnumSet.copyOf(Arrays.asList(elem)), ohne die Klasse übergeben zu müssen.

+0

Aus Gründen, die nicht in dem vereinfachten Beispiel angegeben sind, kann ich V nicht deklarieren, um Enum zu erweitern ; Deshalb habe ich überprüft, ob enum [0] eine Instanz von Enum ist. Ich wusste, dass Typ löschen den Typ von V verlieren würde, weshalb ich nicht für set = Sets.newEnumSet (V.class) versucht habe. – EQvan

+0

@EQvan Ich schlage vor, Sie bearbeiten Ihren Beitrag mit den Einschränkungen dann ... weil, warum versuchen, ein 'EnumSet ' zu konstruieren ist 'V' darf nicht ein Enum sein? Sie müssen den Typ haben, um ein leeres EnumSet zu erstellen. – Tunaki

+0

Ich kann sicherstellen, dass es immer mindestens 1 Element gibt, und EnumSet.copyOf (Arrays.asList (elem)) ist genau, wo ich angefangen habe ... aber das gibt mir einen Fehler "Grenzen nicht übereinstimmen", den ich nicht vollständig verstehe . – EQvan

0

Wenn Sie nicht den generischen Parameter V extends Enum<V> gebunden, können Sie übersetzbar Code machen, wie folgt:

public <V> Set<V> setOf(V... elem) { 
    Set<V> set = null; 
    if (elem[0].getClass().isEnum()) { 
     set = (Set<V>) EnumSet.copyOf((Collection<Enum>)Arrays.asList(elem)) ; 
    } 
    return set; 
} 

Natürlich gibt es unsichere Guss Warnungen.


Ich habe auch die Prüfung des Typs:

if (elem[0].getClass().isEnum()) 

die IMHO sauberer ist.

Verwandte Themen