2016-03-07 3 views
7

Esiste un collegamento singolo per convertire un elenco di stringhe in un insieme di enum? Per esempio, avendo:Convertire un elenco <String> in un set con Java 8

public enum MyVal { 
    ONE, TWO, THREE 
} 

e

List<String> myValues = Arrays.asList("ONE", "TWO", "TWO"); 

vorrei convertire myValues ad un Set<MyVal> contenente gli stessi elementi come:

EnumSet.of(MyVal.ONE, MyVal.TWO) 
+0

http://stackoverflow.com/a/26731123/3641067 –

risposta

20

Sì, è possibile effettuare una Stream<String> dei tuoi elementi, mappali ciascuno al rispettivo valore enum con il mappatore MyVal::valueOf e raccogli quello in una nuova EnumSet con toCollection inizializzato noneOf:

public static void main(String[] args) { 
    List<String> myValues = Arrays.asList("ONE", "TWO", "TWO"); 
    EnumSet<MyVal> set = 
     myValues.stream() 
       .map(MyVal::valueOf) 
       .collect(Collectors.toCollection(() -> EnumSet.noneOf(MyVal.class))); 
    System.out.println(set); // prints "[ONE, TWO]" 
} 

se siete semplicemente interessati ad avere un Set come risultato, non un EnumSet, si può semplicemente utilizzare il built-in di raccolta Collectors.toSet().

+4

Questo conta come un unico rivestimento in questi giorni :-)? – Thilo

+0

Dipende dal numero di caratteri per riga consentito. SO è avaro a questo proposito. – the8472

+1

Invece di 'Collectors.toCollection (() -> EnumSet.noneOf (MyVal.class))' Sto facendo 'Collectors.toSet()' con lo stesso risultato – otonakav

2

Ecco un due-liner (ma più breve):

EnumSet<MyVal> myVals = EnumSet.allOf(MyVal.class); 
myVals.removeIf(myVal -> !myValues.contains(myVal.name())); 

Invece di aggiungere elementi presenti nella lista, è possibile creare un EnumSet con tutti i possibili valori e rimuovere quelli che non sono presenti nella lista .

+1

Interessante. Ha la proprietà leggermente diversa che non genera un'eccezione se una delle stringhe non corrisponde a una enumerazione. Potrebbe o potrebbe non essere desiderabile, a seconda della situazione. – slim