компаратор с отношением один ко многим - PullRequest
0 голосов
/ 14 февраля 2019

У меня есть объект DTO ClientInfo, который содержит список объектов документа.

Я использую следующий метод сравнения для сортировки списка clientInfo по documentCreationDate DESC.

    @Override
        public int compareTo(ClientInfo o) {

            Date firstmaxDate = this.getDocuments().stream().map(d -> d.getCreateDate()).max(Date::compareTo).get();
            Date secondmaxDate = o.getDocuments().stream().map(d -> d.getCreateDate()).max(Date::compareTo).get();
            return firstmaxDate.compareTo(secondmaxDate);

        }
List<ClientInfo> clientInfos= serverReturnedList......;
Collections.sort(clientInfos);

Но его получениеисключение говорит о том, что правило сравнения было нарушено.так что я не получаю ожидаемого результата.Может кто-нибудь объяснить, как это сделать.

Это трассировка стека исключений

java.util.NoSuchElementException: No value present
        at java.util.Optional.get(Optional.java:135)
        at com.orsbv.hcs.dto.ClientInfo.compareTo(ClientInfo.java:346)
        at com.orsbv.hcs.dto.ClientInfo.compareTo(ClientInfo.java:24)
        at java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:320)
        at java.util.ComparableTimSort.sort(ComparableTimSort.java:188)
        at java.util.Arrays.sort(Arrays.java:1312)
        at java.util.Arrays.sort(Arrays.java:1506)
        at java.util.ArrayList.sort(ArrayList.java:1462)
        at java.util.Collections.sort(Collections.java:141)

Ответы [ 2 ]

0 голосов
/ 17 февраля 2019

сначала я добавил поле maxDocuemntCreationDate в clientInfo.

  Date maxCreationDate = clientInfo.getDocuments()
                        .stream()
                        .map(Document :: getCreateDate)
                        .max(Date::compareTo)
                        .orElseGet(Date::new);

Затем я сравнил таким образом

 @Override
            public int compareTo(ClientInfo o) {


              return 
              this.getMaxCreationDate().compareTo(o.getMaxCreationDate());

            }
0 голосов
/ 14 февраля 2019

Вы должны сохранить ваш compareTo() метод в том виде, в котором он написан, потому что он сортируется в соответствии с естественным упорядочением (по возрастанию), что имеет смысл.

Вместо этого вы должны изменить сортировку, чтобы сказать ей сортировать в обратном порядке.(по убыванию).

List<ClientInfo> clientInfoList = ...
Collections.sort(clientInfoList, Comparator.reverseOrder());

ОБНОВЛЕНИЕ на основе информации, добавленной к вопросу:

Некоторые из ваших ClientInfo не имеют документов, которые вы можете использовать для проверки даты создания.

Когда вы делаете это:

 Date firstmaxDate = this.getDocuments().stream().map(d -> d.getCreateDate()).max(Date::compareTo)

max() возвращает Optional<Date>, что позволяет ему возвращать Optional.empty() в случае пустого потока.Если у вас есть ClientInfo без какого-либо документа, вы вызываете get() для пустого Optional, что вызывает это исключение.

Вам необходимо определить, может ли этот случай возникнуть в реальных данных, иесли да, то как вы хотите отсортировать ClientInfo без документа.Если все ваши созданные вами даты уже в прошлом, вы можете просто заменить «нет даты создания» на «сейчас»:

        Date thisDate = this.getDocuments()
                .stream()
                .map(Document::getCreateDate)
                .max(Date::compareTo)
                .orElseGet(Date::new);
        Date otherDate = o.getDocuments()
                .stream()
                .map(Document::getCreateDate)
                .max(Date::compareTo)
                .orElseGet(Date::new);

Или вы можете остановиться до get(), работать с Optional<Date> и проверитьisPresent() и при необходимости обращаться с ним.

...