0

I've a school list which contains class, class list which also contains student and student are also another list. I want to apply two nested filter which first will check that if any class have a empty student list and second filter is for checking that if school has any empty class list and finally it should return the list but I just can't apply two filters as nested, I keep getting syntax error. I'm a bit new to stream api.

result = result.stream()
          .filter(school -> school.getSchoolClassList().stream()
                    .filter(schoolClass-> schoolClass.getStudentList().stream()
                    .anyMatch(schoolClass-> schoolClass.getStudentList().size() > 0))
          .anyMatch(school -> school.getSchoolClassList().size() > 0))
          .collect(Collectors.toList());
2
  • just use .filter(cls-> cls.getStudentList().size() > 0), no need to stream that list. Commented Jan 24, 2022 at 13:23
  • I'm sorry but the result is not really what I want. I want to filter both class and school array. Commented Jan 25, 2022 at 7:56

2 Answers 2

1

You might want to add the resulting Syntax error. However, as I see at first is, that you are using class as an identifier, when it is actually a reserved keyword in Java programming language. Consider renaming the identifiers to something alike schoolClass.

Sign up to request clarification or add additional context in comments.

1 Comment

To give an example first anyMatch method saying that can't resolve getStudentList() method in student type. I used sample code as an example, this task has been given me by the company that I work as an intern
0

I am not sure if I understood you correctly but as far as I got it is that you want to get all schools that either have empty classes or that have classes without students.

What you can do is defining the predicates outside of the stream.

Predicate<School> empty_students_filter = school ->
    school.getSchoolClassList().stream().map(SchoolClass::getStudentList).anyMatch(List::isEmpty);

Predicate<School> empty_classes_filter = school -> school.getSchoolClassList().isEmpty();

Then you can use the predicates inside your filter method and combine them with Predicate.or():

List<School> schools_with_no_or_empty_classes = 
    schools.stream()
           .filter(empty_classes_filter.or(empty_students_filter))
           .collect(Collectors.toList());

Note: if you want to get only the schools that have classes and all classes should have students, then you can adapt the filter as follows with a Predicate.and():

.filter(Predicate.not(empty_classes_filter).and(Predicate.not(empty_students_filter)))

EDIT:

According to your comment, this is not easily doable using the Streams API because you iterate over a Collection of schools and you can only filter schools based on their properties and not filter their properties. So you would need to implement your own custom collector.

I would recommend solving the problem in 2 steps.

Step 1: Remove all classes from a school that contain no students.

Step 2: Stream over and collect all schools that have classes.

//step 1:
result.forEach(school -> {
    List<SchoolClass> school_classes = school.getSchoolClassList();
    List<SchoolClass> empty_classes = 
        school_classes.stream()
                      .filter(school_class -> school_class.getStudentList().isEmpty())
                      .collect(Collectors.toList());
    school.getSchoolClassList().removAll(empty_classes);
});

//step 2:
List<School> remaining_schools = result.stream()
                                       .filter(school -> !school.getSchoolClassList().isEmpty())
                                       .collect(Collectors.toList());

3 Comments

Thank you for this answer but in the first one I want to filter class array but it still filters school array according to class so result is not really what I want
The problem here is if school has 3 classes and one of them doesn't have any students it deletes school from list immediately but other 2 classes have students so I don't want to lose them. That's why filtering should be applied to classes not schools, like don't get classes doesn't have students. But I couldn't find how :(
I will come back to you in about an hour :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.