2015-05-23 19 views
5

Desidero raggruppare un elenco di oggetti contenente un attributo time in intervalli di 5 minuti, preferibilmente utilizzando flussi e collettori.Come raggruppare gli oggetti in un elenco in altri elenchi per Attributo utilizzando gli stream e Java 8?

L'unica soluzione possibile trovata su StackOverflow è calcolare quanti intervalli (sottoliste) ho bisogno, aggiungere ogni oggetto a ciascuna di queste liste e filtrare quelli che non rientrano nel rispettivo intervallo temporale, che non è esattamente una bella soluzione.

(potete trovare il thread qui: How to group elements of a List by elements of another in Java 8)

ho pensato a qualcosa di simile a questo:

List<MyObject> list = new ArrayList<MyObject>(); 
....... 
List<List<MyObject>> grouped = list.stream().collect(Collectors.groupingBy(obj -> obj.getTime()/intervalLength)); 

Questo, naturalmente, lavoro doenst.

Spero che, con Java 8 & le sue funzionalità vengano utilizzate sempre di più, possiamo trovare una soluzione di sinterizzazione per tale problema.

saluti, Claas M.

EDIT: Alla fine, ho usato la soluzione di @Harsh Poddar e convertito la mappa in una lista di liste utilizzando

for(Map.Entry<Integer, List<MyObject>> entry:map.entrySet()) 
    list.add(entry.getValue()); 

Nota: L'elenco ha dovuto essere ordinati in seguito.

risposta

4

Questo funziona tutto bene:

Map<Long,<List<MyObject>> grouped = ticks.stream().collect(Collectors.groupingBy(obj -> obj.getTime()/intervalLength)); 

Questo metodo vi darà una mappa su cui si può quindi chiamare .values ​​() per ottenere l'elenco delle liste. Il primo elemento conterrà gli elementi con obj.getTime() da 0 a intervalLength purché esistano tali elementi. Il secondo conterrà da intervalLength a intervalLength * 2 e così via

+0

Che funzionava, grazie! –

4

Utilizzare una funzione per mappare un tempo per un secchio:

// assume time is in seconds 
int bucketNumber(int baseTime, int thisTime) { 
    return (thisTime - baseTime)/300; 
} 

poi raccogliere per numero secchio:

ticks.stream().collect(groupingBy(e -> bucketNumber(baseTime, e.getTime())); 

Ora avere un Map<Integer, List<Tick>> dove la chiave è l'indice del bucket di cinque minuti che inizia a baseTime e un elenco di tick in quel bucket. Se vuoi solo un istogramma, usa un collettore downstream:

ticks.stream().collect(groupingBy(e -> bucketNumber(baseTime, e.getTime()), 
            counting()); 
+1

@HarshPoddar Fino a voi. Stavo cercando di illustrare come risolvere il problema, dal momento che sembrava che l'OP avesse problemi. –

+0

Grazie per la tua risposta! –

Problemi correlati