3 votes

Comment obtenir la liste unique des objets qui ont la date d'événement la plus élevée dans le champ event_date de la collection Iterable<Student> ?

J'ai un Iterable<Student> studentList qui contient des objets étudiants avec les champs id, event_date et bien d'autres.

Iterable<Student> myStudentList (contains student objects);

Maintenant, cette liste d'étudiants contient plusieurs objets pour un seul identifiant d'étudiant. Supposons que je doive modifier cette liste de manière à ce qu'elle ne contienne qu'un petit nombre d'objets étudiants (un par identifiant d'étudiant et cet objet étudiant doit contenir la date maximale de l'événement pour tous les objets étudiants de son identifiant). Comment puis-je faire cela efficacement ?

Par exemple. Actuellement, la liste contient les éléments suivants

ListIndex  |  Student ID | Student Name | Student Event Date |
0            RV001         Mahesh          1328532774000
1            RV002         James           1328532774000
2            RV002         James           1454763174000
3            RV002         James           1549457671000
4            RV001         Mahesh          1549457671000
5            RV003         Andy            1454763174000

Résultat attendu

Et maintenant mon résultat Iterable<Student> La liste devrait contenir le résultat suivant

ListIndex  |  Student ID | Student Name | Student Event Date |
0            RV001         Mahesh          1549457671000
1            RV002         James           1549457671000
2            RV003         Andy            1454763174000

Comment puis-je réaliser cela efficacement en utilisant Java 8 ?

Ces données proviennent d'une table qui est partitionnée par event_date.

Mon approche actuelle à laquelle je peux penser :-P

Step 1 - Create a HashMap<Student_id, List<Student>>
Step 2 - Create a final List<Student> finalList for result purpose.
Step 2 - Iterate through the List<Student> 
    (a) For each student_id , store the list of Student objects in the  
        Map
         -- END of Iterating List<Student>
Step 3 - Iterate Each Map Entry in HashMap 
        (a) For every key , Apply Comparator on List<Student> for 
         current student id.
        (b) Get the first object of List<Student> in map for current 
            student_id and add it to the final list

Faites-moi savoir si vous avez de meilleures approches.

4voto

nullpointer Points 1135

Vous cherchez peut-être quelque chose comme :

List<Student> finalList = students.stream()
        // group by Id, value as List
        .collect(Collectors.groupingBy(Student::getId, 
        // reduce the list of values to only one with greater event_date 
                Collectors.reducing((student, student2) -> 
                        student.getEvent_date() > student2.getEvent_date() ? student : student2)))
        .values() // stream only such values
        .stream()
        .map(Optional::get)
        .collect(Collectors.toList()); // collect to list

Ou comme Holger l'a fait remarquer, vous pouvez utiliser

.collect(Collectors.toMap(Student::getId, Function.identity(), 
                  (s1, s2) -> s1.getEvent_date() > s2.getEvent_date() ? s1: s2))

Pour ce faire, il faudrait que vous enveloppiez les valeurs de la carte formée ici dans l'élément new ArrayList<>() .

3voto

Ruslan Points 5678

Semblable à la réponse de @nullpointer, mais en supposant que la date de l'événement a int , long o double vous pouvez utiliser maxBy en aval avec comparingInt , comparingLong o comparingDouble comparateur

studentList.stream()
    .collect(groupingBy(Student::getId, 
             maxBy(Comparator.comparingLong(Student::getEventDate))))
    .values()
    .stream()
    .map(Optional::get)
    .collect(toList());

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X