猿问

如何使用Stream过滤嵌套对象?

我想使用 Stream API 过滤嵌套对象。问题是嵌套类太多,使用下面的方法我写了太多重复的代码。


有没有办法在没有重复代码的情况下处理这个流?


public class Country{

    Map<String, City> cities;

}


public class City{

    Map<String, School> schools;

}


public class School{

    String name;

    String address;

    Model model;

}


public class Model{

    String name;

    Teacher teacher;

}


public class Teacher{

    String name;

    String id;

}

我的直播;


country.getCities().values().stream().foreach(

     (City city) ->

         city.getSchools()

             .entrySet()      

             .stream()

             .filter(schoolEntry -> schoolEntry.getValue().getName().equals("test")) 

             .filter(schoolEntry -> schoolEntry.getValue().getModel().getName().equals("test2"))

             .filter(schoolEntry -> schoolEntry.getValue().getModel().getTeacher().getName().equals("test2"))

             .foreach(schoolEntry -> {

                  String schoolKey = schoolEntry.getKey();

                  resultList.put(schoolKey, schoolEntry.getValue().getModel().getTeacher().getId());

              })    

);


ABOUTYOU
浏览 350回答 3
3回答

HUWWW

您可以定义一种方法来使用它Predicate来过滤学校。public static boolean matches(School school, String schoolName, String modelName, String teacherId) {&nbsp; &nbsp; return school.getName().equals(schoolName)&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; && school.getModel().getName().equals(modelName)&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; && school.getModel().getTeacher().getId().equals(teacherId);}将此应用于流:public static Map<String, String> getSchoolAndTeacherFrom(Country country, Predicate<School> schoolWithModelAndTeacher) {&nbsp; &nbsp; return country.getCities().values().stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .flatMap(c -> c.getSchools().entrySet().stream())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .filter(s -> schoolWithModelAndTeacher.test(s.getValue()))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .collect(Collectors.toMap(Entry::getKey, schoolEntry -> schoolEntry.getValue().getModel().getTeacher().getId()));}像这样使用:&nbsp; &nbsp; Country country = <county>&nbsp; &nbsp; Predicate<School> schoolWithModelAndTeacher = school -> matches(school, "test1", "test2", "test2");&nbsp; &nbsp; getSchoolAndTeacherFrom(country, schoolWithModelAndTeacher);一些进一步的想法:如果地图schools使用School.getName()的密钥,那么我们可以这样写:public static Map<String, String> getSchoolAndTeacherFrom(Country country, Predicate<School> schoolWithModelAndTeacher) {&nbsp; &nbsp; return country.getCities().values().stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .flatMap(city -> city.getSchools().values().stream())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .filter(schoolWithModelAndTeacher::test)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .collect(Collectors.toMap(School::getName, school -> school.getModel().getTeacher().getId()));}假设一个国家的学校名称和教师 ID 是唯一的(而模型名称是常见的),则过滤将导致单个值(如果有)。但是就不需要Mapas 结果类型了。类型的结果Entry<String String>会做到这一点。如果谓词的参数仍然是已知的(学校、模型、教师),那么整个事情只是一个问题,即在某个国家/地区是否有给定模型的给定学校的给定教师。然后我们可以写得更短:public static boolean isMatchingSchoolInCountryPresent(Country country, Predicate<School> schoolWithModelAndTeacher) {&nbsp; &nbsp; return country.getCities().values().stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .flatMap(c -> c.getSchools().values().stream())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .anyMatch(schoolWithModelAndTeacher::test);}
随时随地看视频慕课网APP

相关分类

Java
我要回答