【问题标题】:How to Sort List based on Inner Object's property in java 8java 8中如何根据内部对象的属性对列表进行排序
【发布时间】: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;
    }

我有两个不同的表SourceTarget,加入它们后,我在查询输出中得到四列。我正在使用这四列的值构造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&lt;FinalResponse&gt; finalResponses 也未排序。 我希望我的最终输出按照 sourceId 进行排序,所以我这样做了:

finalResponses.sort(Comparator.comparing(finalResponse->finalResponse.getSource().getSourceId()));

它适用于非空值,但如果我在多行上有source(sourceId=null,sourceName=null),那么我会得到NullPointerException。 基于Source 对象的sourceId 属性对集合进行排序的最佳方法是什么?

【问题讨论】:

  • 在您的问题域中是否可以接受空源字段,或者这是一个问题/错误?如果您确实允许空源数据,您希望如何使用Source 作为映射中的键?
  • @basil-bourque 这不是问题,有时是允许的。对于某些情况,可能有targets 而没有sourceMap 正在以 null 作为键正确构建,我已经在 Source and Target 两个类中处理了 equals and hashcode
  • 这能回答你的问题吗? Java 8 sort on Class member's property
  • @tgdavies 正如我所发布的,我尝试了类似的方法,但它不适用于 null 值。

标签: java sorting collections java-stream comparator


【解决方案1】:

应应用Comparator.nullsLastComparator.nullsFirst 来处理比较项目中可能的null 值:

finalResponses.sort(Comparator.nullsLast(
    Comparator.comparing(fr -> fr.getSource().getSourceId())
));

或者像这样:

finalResponses.sort(Comparator.comparing(
    fr -> fr.getSource().getSourceId(),
    Comparator.nullsLast(Comparator.naturalOrder())
));

【讨论】:

    猜你喜欢
    • 2022-01-11
    • 2022-01-05
    • 1970-01-01
    • 2019-06-30
    相关资源
    最近更新 更多