根据取自另一个 class 的值对对象列表进行排序

Sort a list of objects, based on values, taken from another class

我有一个“类别”的对象列表class:

    public class Category {
    
        private String originalId;
        private Double ordinal;
        private String sportId;
        private String sportName;
        private String type;
        private String version;
}

以及“联盟”的对象列表class:

public class League {

    private String leagueName;
    private String originalId;
    private int rank;

    public League(String name, String originalId, int rank) {
        this.leagueName = name;
        this.originalId = originalId;
        this.rank = rank;
    }

这些 class 描述了相同的实体(因此“类别”class 的“originalId”字段值等于“联盟”class 的“originalId”字段值), 但它们的值取自不同的来源,这就是为什么它们从一开始就分开的原因

我需要做的是根据“联盟”中的“等级”字段值对“类别”列表进行排序 class

所以,排序的逻辑应该是这样的:

  1. 对于每个“Category”对象,我会尝试通过比较它们的“originalId”字段来找到对应的“League”对象

  2. 如果找到对应的对象,则从“League”对象中获取“rank”字段的值,并使用它按rank

  3. 如果没有找到对应的对象,则排序时应将此类“类别”对象移至列表末尾

所以,比较器应该是这样的:

public static Comparator<Category> byRank() {
        return nullsLast(comparing(Category::getRankFromCorrespondingLeagueObject, nullsLast(naturalOrder())));
    }

这就是我难过的地方,因为我很少使用从另一个对象中获取的字段值来在排序时使用它

是否有一些简单的好方法可以做到这一点?

创建 League 排名 originalId 的地图,将其提供给您的比较器并使用它。如果您在地图中找不到任何内容,请设置使用 Integer.MIN_VALUE(或 MAX_VALUE,具体取决于您喜欢的订购方式)。这将命令它到结果的末尾。像(有点伪代码):

public static Comparator<Category> byRank(Map<String, Integer> leagueRanks) {
    return new Comparator<Category>() {
      @Override
      public int compare(Category o1, Category o2) {
        return Integer.compare(leagueRanks.getOrDefault(o1.getOriginalId(), Integer.MAX_VALUE), leagueRanks.getOrDefault(o2.getOriginalId(), Integer.MAX_VALUE));
      }
    };
}

要收集 League 等级以进行映射,您可以使用如下方法:

Map<String, Integer> leagueRanks = leagues.stream().collect(Collectors.toMap(it -> it.getOriginalId(), it -> it.getRank()));