具有一对多关系字段的比较器

问题描述 投票:1回答:2

我有一个DTO对象ClientInfo,它包含一个文档实体列表。

我使用以下比较方法按documentCreationDate DESC对clientInfo列表进行排序。

    @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)
java comparable
2个回答
0
投票

你应该保持你的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()并根据需要处理。


1
投票

首先,我向clientInfo添加了一个maxDocuemntCreationDate字段。

  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());

            }
© www.soinside.com 2019 - 2024. All rights reserved.