【问题标题】:Sort a list using parallel sorting and multiple fields使用并行排序和多个字段对列表进行排序
【发布时间】:2017-07-26 10:52:21
【问题描述】:

我有一个对象列表,我根据两个参数对该列表进行排序: 1. 名字,和 2. 姓氏。

所以要求就是,先按名字排序,再按姓氏排序。

我已经使用 Comparator.compairing 和 thenCompairing 方法实现了这一点,如下所示:

Comparator<Employee> groupComparator = Comparator.comparing(Employee::getFirstName)
                                                .thenComparing(Employee::getLastName);

而且,它工作得很好。

现在我想要的是使用并行处理/排序的概念,使用多线程或在多线程环境中进行并行排序。知道如何实现这一目标吗?

【问题讨论】:

    标签: multithreading sorting parallel-processing java-8 comparator


    【解决方案1】:

    稍作修改,但这应该也可以:

    List<Employee> sortedEmployees = employees.parallelStream()
       .sorted(Comparator.comparing(Employee::getFirstName)
                         .thenComparing(Employee::getLastName))
       .collect(Collectors.toList());
    

    您看 - 这是流的优点之一 - 将解决方案变为并行可能就像将 stream() 变为 parallelStream() 一样简单!

    但是像往常一样使用 parallelStream

    • 衡量其影响
    • 准备好迎接惊喜和微调的需要

    【讨论】:

      【解决方案2】:

      我使用 Arrays.parallelSort 方法得到的解决方案如下:

      List<Employee> emps  = getEmployees();
      Comparator<Employee> groupComparator = Comparator.comparing(Employee::getFirstName)
                                                          .thenComparing(Employee::getLastName);
      Employee[] empArr = employees.toArray(new Employee[emps.size()]);
      
      //Parallel sorting
      Arrays.parallelSort(empArr, groupComparator);
      

      已添加 java 8 并根据文档:

      排序算法是一种并行排序合并,它将数组分解为子数组,这些子数组本身已排序然后合并。当子数组长度达到最小粒度时,使用适当的 Arrays.sort 方法对子数组进行排序。如果指定数组的长度小于最小粒度,则使用适当的 Arrays.sort 方法对其进行排序。该算法需要一个不大于原始数组大小的工作空间。 ForkJoin 公共池用于执行任何并行任务。

      这里会解决我的问题

      【讨论】:

        【解决方案3】:

        这也可以通过使用streams 来实现。通过使用streams,我们不需要在排序之前将List 复制到数组中。

        Stream<Employee> sorted = employees.stream()
                                           .sorted(Comparator.comparing(Employee::getFirstName)
                                           .thenComparing(Employee::getLastName))   
                                           .parallel();   
        
        sorted.forEachOrdered(System.out::println);
        

        【讨论】:

        • 这将对数据进行排序,然后,forEach 将以任意顺序打印元素……
        • 那么,正确的做法是收集到一个 List 吗?是否按排序顺序打印?
        • 比较forEachforEachOrdered的合约... 当然,收集到一个列表中会产生一个顺序正确的列表,但这不是必需的,当您只想打印时元素。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-08-27
        • 1970-01-01
        • 1970-01-01
        • 2011-09-14
        • 2012-03-04
        • 1970-01-01
        相关资源
        最近更新 更多