Parallel processing DTOs上具有lamda表达式的流

Parallel processing DTOs上具有lamda表达式的流,parallel-processing,java-8,java-stream,Parallel Processing,Java 8,Java Stream,我有一系列的“学生”班。学生类有两个字段1.private final String firstName;2.私有最终布尔值为当前值 如果学生处于非活动状态,“学生”类中的“checkIsCurrent”api应给出假值 下面是我的DTO课程 /** * A class representing a single student in a single class. */ public final class Student2 { /** * First name of the student

我有一系列的“学生”班。学生类有两个字段1.private final String firstName;2.私有最终布尔值为当前值

如果学生处于非活动状态,“学生”类中的“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;
          }
 }

对此,什么是并行流代码?

您可以使用
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);
return Stream.of(studentArray)
.parallel()
.filter(s->!s.checkIsCurrent())
.map(学生::getFirstName())
.collect(Collectors.groupingBy(Function.identity()、Collectors.counting())
.entrySet()
.stream()
.min(Map.Entry.comparingByValue().reversed())
.map(Entry::getKey).orElse(null);

另一个选项是使用,尽管这要求您覆盖
等于
/
哈希代码

您应该决定您的班级是
学生
还是
学生2
。此外,不要插入任意
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
替换为
toConcurrentMap
,或将
groupingByConcurrent
替换为
groupingBy
,最终得到四个备选测试


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

这个答案如何<代码>数组.stream(studentArray).parallel().filter(s->!s.checkIsCurrent()).map(s->s.getFirstName()).collect(Collectors.toList()).stream().collect(Collectors.groupingBy(Function.identity(),Collectors.counting()).entrySet().stream().max((entry1,entry2)->entry1.getValue()>entry2.getValue()?1:-1.get().getKey();@HadiJeddizahed:插入
.collector.toList()).stream()没有意义
进入管道后,它没有语义效果,但会浪费资源。此外,
(entry1,entry2)->entry1.getValue()>entry2.getValue()?1:-1
是一个无效的比较器,因为它不会为相等的值返回
0
,即使在这种情况下它可能恰好与
max
一起工作。并且没有理由在存在正确的
Map.Entry.comparingByValue()
以及
可选的.get()时手动编写这样的比较器当没有匹配的元素时,
可能会失败…感谢您的回答。是的,
排序(…)。findFirst()
是说“
min
”的一个低效的替代方法,除非流识别并替换它(在当前实现中不会发生这种情况)。您的第一条评论已被考虑。第9次编辑:(.我认为ideone确实适用于智能手机,但我很少使用它。尽管如此,我还是非常感谢您再次提供的有用评论:)。请注意,类型推断对嵌套调用比对链式调用更有效,因此与其使用
Map.Entry.comparingByValue().reversed()
,您可以使用
Map.Entry.comparingByValue(Comparator.reverseOrder())
而不使用显式类型(然后您可以使用
导入静态方法).Mut当使用
max
而不是
min
时,您不需要反转比较器…首先关注正确性,然后考虑并行性是否是合理的优化。