Obter funcionários antes e depois da data específica de ingresso na lista de funcionários com o fluxo Java


9

Tenho Listde Employees com diferentes datas de união. Desejo obter funcionários antes e depois da data específica de ingresso na lista usando fluxos.

eu tentei seguir o código,

 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;
}

Existe alguma maneira de fazer isso no fluxo único?


11
Você pode usarpartitioningBy
Code_Mode

5
Antes e depois - então você quer todos os funcionários, exceto os que se juntaram à data?
John3136 3/01

Supondo que "tenha sido um funcionário pelo menos desde", você desejará se dividir antes e não antes, sem se preocupar com nada.
JollyJoker

Respostas:


16

Você pode usar partitioningBycomo abaixo,

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 Retorna um coletor que particiona os elementos de entrada de acordo com um predicado e os organiza em umMap<Boolean, List<T>>

Observe que isso não vai lidar com funcionários specificDate.


11
Uma explicação do código será ótima.
Vishwa Ratna

2
Isso não faz exatamente o que o código em questão faz - os funcionários com specificDateaterrissarão na falsepartição, o que ocorre no código em questão
Andronicus

Como a adição specificDate.plusDays(1)resolve o problema? specificDateainda estará na falseparte.
Andronicus

Então ele estará na truepartição ...
Andronicus

11
@ Andronicus: Somente o OP sabe se esse comportamento é um bug ou um recurso. Para mim, parece mais seguro não deixar nenhum funcionário de fora.
Eric Duminil

9

Se sua lista puder ter entradas que se juntaram aospecificDate , você poderá achar groupingByútil:

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);

O resultmapa contém Employeeregistros agrupados por posição relativamente a specificDate, para que você possa escolher quem ingressou antes, depois ou na data especificada.


Esta deve ser a resposta aceita
Andronicus

2
-1. Você está assumindo que falso compareToretornará apenas -1, 0 ou 1. De fato, LocalDate.compareTo pode retornar qualquer int.
MikeFHay

11
@ MikeFHay Obrigado por apontar isso. Fiz um teste muito rápido e tirei conclusões precipitadas. Implementação alterada (e de repente parece complexa).
ernest_k 3/01

2
@ernest_k: Você pode usar o original compareToe acessá Integer.signum-lo.
Eric Duminil 03/01

11
@JollyJoker Apenas no caso de você não sabia, você pode conectar-se a uma linha específica no github: como este . Clicar no número da linha altera o URL diretamente. Sinta-se livre para ignorar se você já sabia ou não se importa. ;)
Eric Duminil 03/01

4

Você precisa filtrar os funcionários com essa data específica. Então você pode usar o particionamento:

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);

Isso criará um mapa de coleções com base em se elas cumprem o predicado.


Aprendi partitioningBy hoje.
Vishwa Ratna

Não, você não pode filtrar com data, pois
filtraria

@ Code_Mode oh, sim, eu perdi isso, obrigado!
Andronicus

2

Você pode usar Collectors.groupingBye usar o compareTométodo para agrupar a lista de funcionários com base nas datas anterior, atual 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)));

Então a saída será

key--> -1 ---> will have employees with previous date
key--> 0 ---> will have employees with current date
key--> 1 ---> will have employees with future date
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.