2017-10-08 15 views
2

Il y a deux objets simples pour étudiants et des cours comme celui-ci:filtrer une liste d'objets par son champ de liste

public class Student { 
    List<Course> courses; 
    ... 
} 
public class Course { 
    String name; 
    ... 
} 

Si nous avons un list de Students, comment pouvons-nous filtrer certains des élèves par le nom de leurs cours?

  • premier j'essaie flatMap de répondre à cette question, mais il retourne des objets de cours plutôt que des objets étudiants. Ensuite, j'utilise allMatch (codes suivants). Toutefois, il renvoie la liste des étudiants mais le List est toujours vide. Qu'est-ce que le problème ?
List<Student> studentList; 
List<Student> AlgorithmsCourserStudentList = studentList.stream(). 
    filter(a -> a.stream().allMatch(c -> c.getCourseName.equal("Algorithms"))). 
    collect(Collectors.toList()); 

Répondre

7

Vous devez anyMatch:

List<Student> studentList; 
List<Student> algorithmsCourseStudentList = 
    studentList.stream() 
       .filter(a -> a.getCourses() 
          .stream() 
          .anyMatch(c -> c.getCourseName().equals("Algorithms"))) 
       .collect(Collectors.toList()); 
  • allMatch ne vous donnera Student s que tous leurs Course s sont nommés "Algorithms".

  • anyMatch vous donnera toutes les Student s qui ont au moins un Course nommé "Algorithms".

2

Pour chaque étudiant, obtenez les cours et trouvez s'il y a une correspondance dans les cours de l'étudiant sur le nom du cours.

Course.java:

public class Course { 
    private String name; 

    public String getName() { 
     return name; 
    } 
} 

Student.java:

import java.util.ArrayList; 
import java.util.List; 
import java.util.stream.Collectors; 

public class Student { 
    private List<Course> courses; 

    public List<Course> getCourses() { 
     return courses; 
    } 

    public static void main(String... args) { 
     List<Student> students = new ArrayList<>(); 

     List<Student> algorithmsStudents = students.stream() 
       .filter(s -> s.getCourses().stream().anyMatch(c -> c.getName().equals("Algorithms"))) 
       .collect(Collectors.toList()); 
    } 
} 

modifier:

List<Student> AlgorithmsCourserStudentList = studentList.stream(). 
    filter(a -> a.stream().allMatch(c -> c.getCourseName.equal("Algorithms"))). 
    collect(Collectors.toList()); 
  • Votre code ici ne compilera pas, dans le filtre 'a' est un étudiant, ce qui est fait Il n'y a pas de méthode stream().
  • Vous ne pouvez pas utiliser flatMap() pour convertir la liste des étudiants des cours à un cours d'eau parce que vous pouvez ne pas collecter les étudiants plus loin
  • allMatch rendements true si tous les éléments de la liste correspondent au prédicat, false si il y a un seul élément qui ne correspond pas. Donc, si le code est correct, vous testeriez si tous les cours de l'étudiant portent le nom «Algorithmes», mais vous voulez tester si un seul élément correspond à la condition. Notez que allMatch et anyMatchne pas retourner les listes, ils renvoient un boolean qui est la raison pour laquelle vous pouvez les utiliser dans le filtre.
+0

Vous postez une réponse 10 minutes après on a déjà été affiché et de qualité inférieure à la réponse précédente puisque le vôtre est un peu plus d'une décharge de code et son offre des explications. –

+0

Non, l'autre réponse était incorrecte pendant que je répondais à celui-ci. Il a été modifié pendant que je tapais ceci. –

1

Je suis d'accord avec @Eran.vous pouvez également utiliser method references dans filter comme suit:

students.stream() 
      .filter(s -> s.getCourses().stream() 
        .map(Course::getName) 
        .anyMatch("Algorithms"::equals) 
      ).collect(Collectors.toList());