实现Parallel Stream以获取所有学生详细信息

时间:2018-06-08 18:41:44

标签: list parallel-processing java-8 java-stream

我写了一个服务来获取所有班级学生的完整细节。该服务工作正常,但问题是获取完整的详细信息需要很长时间。我的代码如下所示

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并行流是否合适,这是否真的能提高性能,我也可以在这种方法中实现并行流。

3 个答案:

答案 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();