意外的排序列表
Unexpected sorted list
问候,
我有 2 个对象:
- 请愿书
- Signataire(签字人)
我写了这段代码:
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() return 一个列表。
但结果不是我所期望的:
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]
如你所见,倒数第二不是好的。
你知道为什么比较器不工作吗?
当您链接两个排序时,结果是预期的。
第一个 (.sorted(Comparator.comparingInt(petition -> 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 开始,您可以创建 Comparator
并将它们组合起来,这主要归功于 .thenComparingXXX()
和 .reversed()
方法。
所以你可以这样做:
.sorted(Comparator.comparingInt(petition -> petition.getSignataires().size())
.reversed()
)
您不需要两次 sorted
操作。它们不会合并生成结果 Comparator
.
第一个为 int size()
值构造一个 Comparator<Integer>
,而第二个 忽略前一个调用 并应用它自己的 Comparator<Petition>
(Comparator.<Petition>reverseOrder()
).
Comparator<Petition> reversedSignaturesSizeComparator
= Comparator.<Petition>comparingInt(p -> p.getSignataires().size()).reversed();
List<Petition> resultList = petitionList.stream()
.sorted(reversedSignaturesSizeComparator)
.collect(Collectors.toList());
下面是另一种使用 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());
问候,
我有 2 个对象:
- 请愿书
- Signataire(签字人)
我写了这段代码:
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() return 一个列表。
但结果不是我所期望的:
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]
如你所见,倒数第二不是好的。 你知道为什么比较器不工作吗?
当您链接两个排序时,结果是预期的。
第一个 (.sorted(Comparator.comparingInt(petition -> 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 开始,您可以创建 Comparator
并将它们组合起来,这主要归功于 .thenComparingXXX()
和 .reversed()
方法。
所以你可以这样做:
.sorted(Comparator.comparingInt(petition -> petition.getSignataires().size())
.reversed()
)
您不需要两次 sorted
操作。它们不会合并生成结果 Comparator
.
第一个为 int size()
值构造一个 Comparator<Integer>
,而第二个 忽略前一个调用 并应用它自己的 Comparator<Petition>
(Comparator.<Petition>reverseOrder()
).
Comparator<Petition> reversedSignaturesSizeComparator
= Comparator.<Petition>comparingInt(p -> p.getSignataires().size()).reversed();
List<Petition> resultList = petitionList.stream()
.sorted(reversedSignaturesSizeComparator)
.collect(Collectors.toList());
下面是另一种使用 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());