Неожиданный отсортированный список - PullRequest
0 голосов
/ 12 сентября 2018

Приветствие,

У меня есть 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 () возвращает список.

, но результат оказался не таким, как я ожидал:

enter image description here

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 не выполняет эту работу?

Ответы [ 3 ]

0 голосов
/ 12 сентября 2018

Вам не нужно две sorted операции. Они не будут объединены для получения результирующего Comparator.

Первый создает Comparator<Integer> для int size() значений, а второй игнорирует предыдущий вызов и применяет свой собственный 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());
0 голосов
/ 12 сентября 2018

Ниже приведен еще один способ сделать это с помощью другого перегруженного метода 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());
0 голосов
/ 12 сентября 2018

Результат ожидается при цепочке двух сортировок.
Первая (.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 s и комбинироватьони в основном благодаря методам .thenComparingXXX() и .reversed().

Чтобы вы могли сделать:

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