【发布时间】:2022-01-25 11:04:04
【问题描述】:
我的类结构类似于:
class FinalResponse {
Source source;
List<Target> targets;
}
class Response {
Source source;
Target target;
}
class Source {
Long sourceId;
String sourceName;
}
class Target {
Long targetId;
String targetName;
}
我有两个不同的表Source 和Target,加入它们后,我在查询输出中得到四列。我正在使用这四列的值构造Response 对象。我在具有这 4 个属性sourceId, sourceName, targetId, targetName 的响应对象中有数据。
我可以在多行上使用相同的 sourceId, sourceName,但 targetId, targetName 总是不同的。
我将所有target 对象分组到source 相同的列表中。
List<FinalResponse> finalResponses = responses.stream()
.collect(Collectors.groupingBy(
Response::getSource,
LinkedHashmap::new,
Collectors.mapping(Response::getTarget, Collectors.toList())
)) // Map<Source, List<Target>> is built
.entrySet()
.stream() // Stream<Map.Entry<Source, List<Target>>>
.map(e -> new FinalResponse(e.getKey(), e.getValue()))
.collect(Collectors.toList());
但有时来自数据库的响应无法排序,即使它已排序并且我使用了LinkedHashmap::new,那么我的最终输出 List<FinalResponse> finalResponses 也未排序。
我希望我的最终输出按照 sourceId 进行排序,所以我这样做了:
finalResponses.sort(Comparator.comparing(finalResponse->finalResponse.getSource().getSourceId()));
它适用于非空值,但如果我在多行上有source(sourceId=null,sourceName=null),那么我会得到NullPointerException。
基于Source 对象的sourceId 属性对集合进行排序的最佳方法是什么?
【问题讨论】:
-
在您的问题域中是否可以接受空源字段,或者这是一个问题/错误?如果您确实允许空源数据,您希望如何使用
Source作为映射中的键? -
@basil-bourque 这不是问题,有时是允许的。对于某些情况,可能有
targets而没有source。Map正在以null作为键正确构建,我已经在Source and Target两个类中处理了equals and hashcode。 -
这能回答你的问题吗? Java 8 sort on Class member's property
-
@tgdavies 正如我所发布的,我尝试了类似的方法,但它不适用于
null值。
标签: java sorting collections java-stream comparator