根据取自另一个 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
所以,排序的逻辑应该是这样的:
对于每个“Category”对象,我会尝试通过比较它们的“originalId”字段来找到对应的“League”对象
如果找到对应的对象,则从“League”对象中获取“rank”字段的值,并使用它按rank
如果没有找到对应的对象,则排序时应将此类“类别”对象移至列表末尾
所以,比较器应该是这样的:
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()));
我有一个“类别”的对象列表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
所以,排序的逻辑应该是这样的:
对于每个“Category”对象,我会尝试通过比较它们的“originalId”字段来找到对应的“League”对象
如果找到对应的对象,则从“League”对象中获取“rank”字段的值,并使用它按rank
如果没有找到对应的对象,则排序时应将此类“类别”对象移至列表末尾
所以,比较器应该是这样的:
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()));