Ottieni dipendenti prima e dopo la data specifica di iscrizione dall'elenco dei dipendenti con flusso Java


9

Ho Listdelle Employees con date di iscrizione diverse. Voglio ottenere dipendenti prima e dopo la data specifica di iscrizione dalla lista usando i flussi.

ho provato a seguire il codice,

 List<Employee> employeeListAfter = employeeList.stream()
                .filter(e -> e.joiningDate.isAfter(specificDate))
                .collect(Collectors.toList());

List<Employee> employeeListBefore = employeeList.stream()
        .filter(e -> e.joiningDate.isBefore(specificDate))
        .collect(Collectors.toList());

class Employee{
    int id;
    String name;
    LocalDate joiningDate;
}

C'è un modo per farlo in un singolo flusso?


1
È possibile utilizzarepartitioningBy
— Code_Mode

5
Prima e dopo - quindi vuoi tutti i dipendenti tranne quelli che si sono uniti alla data?
— John 3136,

Supponendo che "sia stato un dipendente almeno da", ti consigliamo di dividerlo prima e non prima, senza preoccuparti affatto.
— JollyJoker il

Risposte:


16

Puoi usare partitioningBycome di seguito,

Map<Boolean, List<Employee>> listMap = employeeList.stream()
        .collect(Collectors.partitioningBy(e -> e.joiningDate.isAfter(specificDate)));

List<Employee> employeeListAfter = listMap.get(true);
List<Employee> employeeListBefore = listMap.get(false);

partitioningBy Restituisce un Collector che suddivide gli elementi di input in base a un Predicato e li organizza in aMap<Boolean, List<T>>

Si noti che questo non gestirà i dipendenti con specificDate.


1
Una spiegazione del codice sarà eccezionale.
— Vishwa Ratna,

2
Questo non fa esattamente ciò che fa il codice in questione - i dipendenti con specificDateatterreranno in falsepartizione, dove non si trova il codice in questione in nessuno
— Andronicus

In che modo l'aggiunta specificDate.plusDays(1)risolve il problema? specificDatesarà ancora nella falseparte.
— Andronico

Quindi sarà nella truepartizione ...
— Andronico

1
@Andronicus: solo OP sa se questo comportamento è un bug o una funzionalità. A me sembra più sicuro non escludere alcun dipendente.
— Eric Duminil,

9

Se il tuo elenco può contenere voci unite alspecificDate , potresti trovare groupingByutile:

Map<Integer, List<Employee>> result = employeeList.stream()
    .map(emp -> new AbstractMap.SimpleEntry<>(specificDate.compareTo(emp.getJoiningDate()), emp))
    .collect(Collectors.groupingBy(entry -> entry.getKey() > 0 ? 1 : (entry.getKey() < 0 ? -1 : 0),
            Collectors.mapping(entry -> entry.getValue(), Collectors.toList())));

employeeListAfter = result.get(-1);
employeeListBefore = result.get(1);
employeeListOnSpecificDate = result.get(0);

La resultmappa contiene Employeerecord raggruppati per posizione relativamente a specificDate, quindi puoi scegliere chi si è unito prima, dopo o alla data specificata.


Questa dovrebbe essere la risposta accettata
— Andronico

2
-1. Stai compareToassumendo il falso presupposto che restituirà solo -1, 0 o 1. In realtà LocalDate.compare Per restituire qualsiasi int.
— MikeFHay,

1
@MikeFHay Grazie per averlo sottolineato. Ho fatto un test molto veloce e sono saltato alle conclusioni. Implementazione modificata (e improvvisamente sembra complessa).
— ernest_k,

2
@ernest_k: è possibile utilizzare l'originale compareToe chiamarlo Integer.signum.
— Eric Duminil,

1
@JollyJoker Nel caso in cui non lo sapessi, puoi collegarti a una linea specifica in github: in questo modo . Facendo clic sul numero di riga si modifica direttamente l'URL. Sentiti libero di ignorare se lo sapevi già o non ti interessa. ;)
— Eric Duminil il

4

Devi filtrare i dipendenti con questa data particolare. Quindi è possibile utilizzare il partizionamento:

Map<Boolean, List<Employee>> partitioned = employeeList.stream()
    .filter(e -> !e.joiningDate.equals(specificDate))
    .collect(partitioningBy(e -> e.joiningDate.isAfter(specificDate)));

List<Employee> employeeListAfter = partitioned.get(true);
List<Employee> employeeListBefore = partitioned.get(false);

Ciò creerà una mappa delle raccolte in base al soddisfacimento del predicato.


Imparato partitioningBy oggi
— Vishwa Ratna,

No, non puoi filtrare con la data poiché
— filtrerebbe i

@Code_Mode oh, sì, mi sono perso, grazie!
— Andronico

2

È possibile utilizzare Collectors.groupingBye utilizzare il compareTometodo per raggruppare l'elenco dei dipendenti in base alla data precedente, corrente e futura

Map<Integer, List<Employee>> result = employeeList.stream()
            .collect(Collectors.groupingBy(e-> e.joiningDate.compareTo(specificDate)< 0 ? -1 : (e.joiningDate.compareTo(specificDate) == 0 ? 0 : 1)));

Quindi l'output sarà

key--> -1 ---> will have employees with previous date
key--> 0 ---> will have employees with current date
key--> 1 ---> will have employees with future date
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.