我写了一个服务来获取所有班级学生的完整细节。该服务工作正常,但问题是获取完整的详细信息需要很长时间。我的代码如下所示
List<StudentsDetails> allStudentsDetails = Lists.newArrayList();
List<ClassDetails> allClassDetailsDetails = getAllClassDetails();
allClassDetailsDetails.forEach(classDetailsDetails-> {
StudentsDetails studentsDetails = new StudentsDetails();
studentsDetails.setClassName(classDetailsDetails.getClassName());
List<Student> allStudents = studentService.getAllStudentsByClass(classDetailsDetails.getClassName());
studentsDetails.setAllStudents(allStudents);
allStudentsDetails.add(studentsDetails);
});
我的问题
在这种情况下使用Java8并行流是否合适,这是否真的能提高性能,我也可以在这种方法中实现并行流。
答案 0 :(得分:0)
这是您并行化操作的方式,但无法保证性能优势,因为它还取决于外部数据库。
Function<ClassDetails, StudentsDetails> fetchStudentDetials = classDetailsDetails -> {
StudentsDetails studentsDetails = new StudentsDetails();
studentsDetails.setClassName(classDetailsDetails.getClassName());
List<Student> allStudents = studentService.getAllStudentsByClass(classDetailsDetails.getClassName());
studentsDetails.setAllStudents(allStudents);
return studentsDetails;
};
List<StudentsDetails> allStudentsDetails = allClassDetailsDetails
.parallelStream()
.map(fetchStudentDetials)
.collect(toList());
答案 1 :(得分:0)
代码缓慢来自数据库访问。
首先,您应该为数据库编制索引。
其次,如果您的学生数据库不是很高,我建议您一次性完成:
List<Student> findStudentByClassNameIn(List<String> classNames);
然后将您的学生映射到您的班级。
// Map class name with its student
Map<String, List<Student>> stdMap = listStudents().stream().collect(groupingBy(Student::getClassName), toList());
List<StudentsDetails> allStudentsDetails = allClassDetailsDetails.stream()
.parallel()
.map(c -> new StudentDetails(stdMap.get(c.getClassName()))
.collect(toList());
第三,如果您的学生数据太大而无法一次性获取,那么请一次性分解以获得30个课程数据。
答案 2 :(得分:0)
试试我的图书馆AbacusUtil。它应该比原始问题中的代码快几十倍:
List<StudentsDetails> allStudentsDetails = StreamEx.of(allClassDetailsDetails).parallel(maxThreadNum) // genernally maxThreadNum = 30 is a good choice.
.map(c -> new StudentsDetails(c.getClassName(), studentService.getAllStudentsByClass(c.getClassName())))
.toList();