在DTO上使用lamda表达式进行流式处理

时间:2018-01-08 09:45:05

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

我有一群学生'类。 Student类有两个字段1.private final String firstName; 2.private final boolean isCurrent;

' checkIsCurrent' api出现在'学生'如果学生不活动,班级应给予虚假价值。

以下是我的DTO课程。

/**
* A class representing a single student in a single class.
*/
public final class Student2 {
/**
 * First name of the student.
 */
private final String firstName;
/**
 * Whether the student is currently enrolled, or has already completed the
 * course.
 */
private final boolean isCurrent;

/**
 * Constructor.
 * @param setFirstName Student first name
 * @param setIsCurrent Student currently enrolled?
 */
public Student2(final String setFirstName,final boolean setIsCurrent) {
    this.firstName = setFirstName;
    this.isCurrent = setIsCurrent;
}

/**
 * Get the first name of this student.
 * @return The student's first name.
 */
public String getFirstName() {
    return firstName;
}


/**
 * Check if this student is active, or has taken the course in the past.
 * @return true if the student is currently enrolled, false otherwise
 */
public boolean checkIsCurrent() {
    return isCurrent;
}
}

现在我想知道不活跃学生最常见的名字?

我想用并行流做这个吗?

 public String mostCommonFirstNameOfInactiveStudentsParallelStream(final Student[] studentArray) {
       try{
            return Stream.of(studentArray)
                     .parallel()
                     .filter(s->!s.checkIsCurrent())
                     .map(s->s.getFirstName())                   
          }
          catch(Exception e){
             throw e;
          }
 }

这将是什么并行流代码?

2 个答案:

答案 0 :(得分:4)

您应该决定您的课程是Student还是Student2。此外,不要插入任意try … catch块。

实现目标的一种方法是

public String mostCommonFirstNameOfInactiveStudentsParallelStream(Student2[] studentArray){
    return Arrays.stream(studentArray)
             .parallel()
             .filter(s->!s.checkIsCurrent())
             .collect(Collectors.toMap(Student2::getFirstName, s -> 1, Integer::sum))
             .entrySet().stream()
             .max(Map.Entry.comparingByValue())
             .map(Map.Entry::getKey)
             .orElse(null);
}

另一种选择是

public String mostCommonFirstNameOfInactiveStudentsParallelStream(Student2[] studentArray){
    return Arrays.stream(studentArray)
             .parallel()
             .filter(s->!s.checkIsCurrent())
             .collect(Collectors.groupingByConcurrent(Student2::getFirstName,
                                                      Collectors.summingInt(s -> 1)))
             .entrySet().stream()
             .max(Map.Entry.comparingByValue())
             .map(Map.Entry::getKey)
             .orElse(null);
}

哪一个更快,取决于几种情况。您也可以将toMap替换为toConcurrentMapgroupingByConcurrent替换groupingBy,最后选择四种替代方案进行测试。

但最有可能的是,顺序流无论如何都会比并行流更快,因为你不太可能有这么多的对象,并行处理会得到回报。

答案 1 :(得分:3)

您可以使用groupingBy收藏家:

   return Stream.of(studentArray)
                .parallel()
                .filter(s -> !s.checkIsCurrent()) 
                .map(Student::getFirstName())   
                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
                .entrySet()
                .stream()
                .min(Map.Entry.<String, Long>comparingByValue().reversed())
                .map(Entry::getKey).orElse(null);

另一种选择是使用Collections.frequency,但这需要您覆盖equals / hashcode