Spesso v'è la necessità di trasformare i risultati per una query del tipo:Lista <Object[]> a Map <K, V> in Java 8
select category, count(*)
from table
group by category
a una mappa in cui le chiavi sono categorie e valori sono conteggio di record appartenenti alla stessa categoria .
Molti framework di persistenza restituiscono i risultati di tale query come List<Object[]>
, in cui gli array di oggetti contengono due elementi (categoria e il conteggio per ciascuna riga di serie di risultati restituita).
Sto cercando di trovare il modo più leggibile per convertire questa lista nella mappa corrispondente.
Naturalmente, tradizionale approccio comporterebbe la creazione della mappa e mettere manualmente le voci:
Map<String, Integer> map = new HashMap<>();
list.stream().forEach(e -> map.put((String) e[0], (Integer) e[1]));
Il primo one-liner che è venuto in mente è stato quello di utilizzare l'out of the box disponibili Collectors.toMap
collezionista:
Map<String, Integer> map = list.stream().collect(toMap(e -> (String) e[0], e -> (Integer) e[1]));
Tuttavia, trovo questa sintassi e -> (T) e[i]
un po 'meno leggibile rispetto all'approccio tradizionale. Per ovviare a questo, ho potuto creare un metodo util che posso riutilizzare in tutte queste situazioni:
public static <K, V> Collector<Object[], ?, Map<K, V>> toMap() {
return Collectors.toMap(e -> (K) e[0], e -> (V) e[1]);
}
Poi ho un perfetto one-liner:
Map<String, Integer> map = list.stream().collect(Utils.toMap());
C'è anche bisogno di cast chiave e valore a causa dell'inferenza di tipo. Tuttavia, questo è un po 'più difficile da comprendere per altri lettori del codice (Collector<Object[], ?, Map<K, V>>
nella firma del metodo util, ecc.).
Mi chiedo, c'è qualcos'altro nella cassetta degli attrezzi di java 8 che potrebbe aiutare questo risultato in un modo più leggibile/elegante?
Hai già un codice funzionante che è una singola riga. Non sono sicuro di quali siano più "strumenti" di cui hai bisogno. A che tipo di risposte sei interessato? – Tunaki
Quello che stai facendo sembra andare bene, tranne che passarei un 'Classe' e 'Classe ' a 'toMap' in modo che i cast possano essere controllati. –
Radiodef
@ Trueki True. Ma penso che sarebbe utile per me e per gli altri vedere esempi di come questo possa essere ulteriormente migliorato, in modo che possa essere applicato in questo e in simili casi d'uso. –