2015-07-29 2 views
21

Esiste un modo migliore di convertire una matrice di stringhe sotto forma di "chiave: valore" in un Map utilizzando la sintassi lambda Java 8?Converti array di stringhe in mappa utilizzando Java 8 espressioni Lambda

Arrays.asList("a:1.0", "b:2.0", "c:3.0") 
     .stream() 
     .map(elem -> elem.split(":") 
     .collect(Collectors.toMap(keyMapper?, valueMapper?)); 

La soluzione che ho in questo momento non sembra davvero funzionale:

Map<String, Double> kvs = new HashMap<>(); 
Arrays.asList("a:1.0", "b:2.0", "c:3.0") 
     .stream() 
     .map(elem -> elem.split(":")) 
     .forEach(elem -> kvs.put(elem[0], Double.parseDouble(elem[1]))); 

risposta

36

È possibile modificare la soluzione per raccogliere il Stream di String array in un Map (invece di utilizzare forEach):

Map<String, Double> kvs = 
    Arrays.asList("a:1.0", "b:2.0", "c:3.0") 
     .stream() 
     .map(elem -> elem.split(":")) 
     .collect(Collectors.toMap(e -> e[0], e -> Double.parseDouble(e[1])); 

Ovviamente questa soluzione non ha alcuna protezione contro input non validi. Forse si dovrebbe aggiungere un filtro nel caso in cui la stringa divisa non ha separatore:

Map<String, Double> kvs = 
    Arrays.asList("a:1.0", "b:2.0", "c:3.0") 
     .stream() 
     .map(elem -> elem.split(":")) 
     .filter(elem -> elem.length==2) 
     .collect(Collectors.toMap(e -> e[0], e -> Double.parseDouble(e[1])); 

Questo ancora non protegge contro tutti gli ingressi non validi (ad esempio "c:3r" causerebbe NumberFormatException per essere gettato da parseDouble).

+6

Non credo che ignorare in silenzio input errati sia un buon consiglio e questo non è stato richiesto dall'OP. Farò meglio a usare 'elem -> elem.split (": ", 2)' invece di aggiungere il passo 'filter'. In questo modo, l'input errato si manifesterà con 'ArrayIndexOutOfBoundsException' (se non è stato trovato alcun colon) o con' NumberFormatException' (se sono stati trovati più di due punti). –

+0

Grazie per tutti i commenti e l'input aggiuntivo sul controllo degli errori. Questo è quello di cui avevo bisogno. – bsam

+0

Se l'attività è di convertire un array * real * in Map, l'espressione dovrebbe iniziare con 'Arrays.stream ()' –

1

risposta parziale, come si sta cercando di miglioramento: la segnalazione

Stream.of("a:1.0", "b:2.0", "c:3.0") 
    .map(...) 
    ... 

errore con un flusso sembra difficile.

Un programma di creazione mappe potrebbe aumentare la soglia, se "a", 1.0 era consentito.

+0

Che cos'è 'String: matches'? –

+0

@TagirValeev Restituisce 'true' se' String' corrisponde al parametro 'regex' specificato. –

+0

@TagirValeev Typo, avrebbe dovuto essere '::' - 'if (" a: 10 ".matches (". * \\:. *) System.out.println ("Contiene due punti"); 'regex corrispondente su tutti –