具有一对多关系字段的比较器
comparator with one to many relation filed
我有一个包含文档实体列表的 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)
您应该保留您的 compareTo()
方法,因为它是根据自然顺序(升序)排序的,这是有道理的。
相反,您应该更改排序,告诉它按相反(降序)顺序排序。
List<ClientInfo> clientInfoList = ...
Collections.sort(clientInfoList, Comparator.reverseOrder());
更新基于添加到问题的信息:
您的一些 ClientInfo
没有任何可用于检查创建日期的文档。
当你这样做时:
Date firstmaxDate = this.getDocuments().stream().map(d -> d.getCreateDate()).max(Date::compareTo)
max()
return 一个 Optional<Date>
允许它在空流的情况下 return Optional.empty()
。当您有一个没有任何文档的 ClientInfo 时,您是在空 Optional
上调用 get()
,这会导致此异常。
您需要确定这种情况是否会出现在真实数据中,如果会出现,您希望如何对没有文档的ClientInfo 进行排序。如果您所有的 createdDates 都是过去的,您可以简单地将 "no created date" 替换为 "now":
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()
并根据需要进行处理。
首先我向 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());
}
我有一个包含文档实体列表的 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)
您应该保留您的 compareTo()
方法,因为它是根据自然顺序(升序)排序的,这是有道理的。
相反,您应该更改排序,告诉它按相反(降序)顺序排序。
List<ClientInfo> clientInfoList = ...
Collections.sort(clientInfoList, Comparator.reverseOrder());
更新基于添加到问题的信息:
您的一些 ClientInfo
没有任何可用于检查创建日期的文档。
当你这样做时:
Date firstmaxDate = this.getDocuments().stream().map(d -> d.getCreateDate()).max(Date::compareTo)
max()
return 一个 Optional<Date>
允许它在空流的情况下 return Optional.empty()
。当您有一个没有任何文档的 ClientInfo 时,您是在空 Optional
上调用 get()
,这会导致此异常。
您需要确定这种情况是否会出现在真实数据中,如果会出现,您希望如何对没有文档的ClientInfo 进行排序。如果您所有的 createdDates 都是过去的,您可以简单地将 "no created date" 替换为 "now":
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()
并根据需要进行处理。
首先我向 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());
}