Obtenir des employés avant et après la date précise d'adhésion à partir de la liste des employés avec le flux Java


9

J'ai Listdes Employees avec différentes dates d'adhésion. Je souhaite obtenir des employés avant et après une date précise d'adhésion à partir de la liste à l'aide de flux.

j'ai essayé de suivre le code,

 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-t-il un moyen de le faire en un seul flux?


1
Vous pouvez utiliserpartitioningBy
— Code_Mode

5
Avant et après - vous voulez donc tous les employés sauf ceux qui se sont joints à la date?
— John3136

En supposant que "ça a été un employé au moins depuis", vous voudrez vous séparer avant et non avant, ne pas vous soucier du tout.
— JollyJoker

Réponses:


16

Vous pouvez utiliser partitioningBycomme ci-dessous,

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 Renvoie un collecteur qui partitionne les éléments d'entrée en fonction d'un prédicat et les organise en unMap<Boolean, List<T>>

Notez que cela ne gérera pas les employés avec specificDate.


1
Une explication du code sera géniale.
— Vishwa Ratna

2
Cela ne fait pas exactement ce que fait le code en question - les employés avec specificDateatterriront en falsepartition, alors que dans le code en question aucun
— Andronicus

Comment l'ajout specificDate.plusDays(1)résout-il le problème? specificDatesera toujours dans la falsepartie.
— Andronicus

Ensuite, ce sera dans la truepartition ...
— Andronicus

1
@Andronicus: Seul OP sait si ce comportement est un bogue ou une fonctionnalité. Pour moi, il semble plus sûr de ne laisser aucun employé de côté.
— Eric Duminil

9

Si votre liste peut contenir des entrées qui se sont jointes à laspecificDate , vous pouvez trouver 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 resultcarte contient des Employeeenregistrements regroupés par position par rapport à specificDate, de sorte que vous pouvez choisir qui s'est joint avant, après ou à la date spécifiée.


Cela devrait être la réponse acceptée
— Andronicus

2
-1. Vous faites la fausse hypothèse qui compareTone renverra que -1, 0 ou 1. En fait, LocalDate.compareTo peut renvoyer n'importe quel entier.
— MikeFHay

1
@MikeFHay Merci de l'avoir signalé. J'ai fait un test très rapide et sauté aux conclusions. Implémentation modifiée (et soudain, cela semble complexe).
— ernest_k

2
@ernest_k: Vous pouvez utiliser l'original compareToet y faire appel Integer.signum.
— Eric Duminil

1
@JollyJoker Juste au cas où vous ne le sauriez pas, vous pouvez créer un lien vers une ligne spécifique dans github: comme ceci . Un clic sur le numéro de ligne modifie directement l'URL. N'hésitez pas à ignorer si vous le saviez déjà ou si vous ne vous en souciez pas. ;)
— Eric Duminil

4

Vous devez filtrer les employés avec cette date particulière. Ensuite, vous pouvez utiliser le partitionnement:

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

Cela créera une carte des collections en fonction de si elles remplissent le prédicat.


Appris partitioningBy aujourd'hui.
— Vishwa Ratna

Non, vous ne pouvez pas filtrer avec la date car cela filtrerait les employés avec seulement specificDate
— Code_Mode

@Code_Mode oh, oui, ça m'a manqué, merci!
— Andronicus

2

Vous pouvez utiliser Collectors.groupingByet utiliser la compareTométhode pour regrouper la liste des employés en fonction de la date précédente, actuelle et future

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

Ainsi, la sortie sera

key--> -1 ---> will have employees with previous date
key--> 0 ---> will have employees with current date
key--> 1 ---> will have employees with future date
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.