【问题标题】:Unexpected sorted list意外的排序列表
【发布时间】:2019-02-17 03:46:00
【问题描述】:

问候,

我有 2 个对象:

  • 请愿书
  • 签字人(签字人)

我写了这段代码:

public List<Petition> getTheMostSigned(long groupId){

    List<Petition> petitionList = petitionPersistence.findByStatusAndGroupId(0,groupId);

    _log.info("list avant getTheMostSigned size  : "+petitionList.stream().map(petition -> petition.getSignataires().size()).collect(Collectors.toList()));

    List<Petition> resultList = petitionList.stream()
            .sorted(Comparator.comparingInt(petition -> petition.getSignataires().size()))
            .sorted(Collections.reverseOrder())
            .collect(Collectors.toList());

    _log.info("list apres getTheMostSigned size  : "+resultList.stream().map(petition -> petition.getSignataires().size()).collect(Collectors.toList()));

    return resultList;

getSignataires() 返回一个列表。

但结果不是我所期望的:

2018-09-12 12:44:25.686 INFO  [http-nio-8080-exec-10][PetitionLocalServiceImpl:390] list avant getTheMostSigned size  : [0, 0, 400, 0, 3, 401, 5501]
2018-09-12 12:44:25.856 INFO  [http-nio-8080-exec-10][PetitionLocalServiceImpl:396] list apres getTheMostSigned size  : [5501, 401, 3, 0, 0, **400**, 0]

如您所见,倒数第二不是好。 你知道为什么 Comparator 不做这项工作吗?

【问题讨论】:

  • 使用sorted() 两次只是浪费。结果顺序将完全由两者中的后者决定。

标签: java list lambda comparator


【解决方案1】:

当您链接两种类型时,结果是预期的。
第一个(.sorted(Comparator.comparingInt(petition -&gt; petition.getSignataires().size()))按列表字段大小排序)。 那么第二个 (.sorted(Collections.reverseOrder())) 会覆盖第一个排序结果,因为最后一个会根据 Petition 的逆自然顺序进行排序。
当您调用两次排序流操作时,大致上就像您使用了这个逻辑:

List<Petition> petitionList = ...;
// first sort
petitionList.sort(Comparator.comparingInt(petition -> petition.getSignataires().size());
// second sort
petitionList.sort(Collections.reversed());

您需要定义一个结合了这些约束的Comparator 实例。
从 Java 8 开始,您可以创建 Comparators 并将它们组合起来,这主要归功于 .thenComparingXXX().reversed() 方法。

所以你可以这样做:

.sorted(Comparator.comparingInt(petition -> petition.getSignataires().size())
                  .reversed()
       )

【讨论】:

    【解决方案2】:

    您不需要两个 sorted 操作。它们不会被组合生成Comparator

    第一个为int size() 值构造一个Comparator&lt;Integer&gt;,而第二个忽略之前的调用并应用它自己的Comparator&lt;Petition&gt; (Comparator.&lt;Petition&gt;reverseOrder())。

    Comparator<Petition> reversedSignaturesSizeComparator 
            = Comparator.<Petition>comparingInt(p -> p.getSignataires().size()).reversed();
    List<Petition> resultList = petitionList.stream()
                                            .sorted(reversedSignaturesSizeComparator)
                                            .collect(Collectors.toList());
    

    【讨论】:

      【解决方案3】:

      下面是使用 Collection 的其他重载方法的另一种方法,该方法使用自定义压缩器

      Comparator<Petition> cmp = 
               (Petition left, Petition right) -> 
                    left.getSignataires().size() - right.getSignataires().size();
      
      List<Petition> resultList = petitionList.stream()
              .sorted(Collections.reverseOrder(cmp))
              .collect(Collectors.toList());
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-04
        • 2021-11-22
        • 2013-04-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多