使用部分显式命令然后另一个命令?
Ordering with partial explicit and then another order?
我需要以自定义方式订购列表,我正在研究正确的方式并找到番石榴的订购 api 但问题是我订购的列表并不总是如此一样,我只需要 2 个字段位于列表的顶部,例如我有这个:
List<AccountType> accountTypes = new ArrayList<>();
AccountType accountType = new AccountType();
accountType.type = "tfsa";
AccountType accountType2 = new AccountType();
accountType2.type = "rrsp";
AccountType accountType3 = new AccountType();
accountType3.type = "personal";
accountTypes.add(accountType3);
accountTypes.add(accountType2);
accountTypes.add(accountType);
//The order I might have is : ["personal", "rrsp", "tfsa"]
//The order I need is first "rrsp" then "tfsa" then anything else
我尝试使用自定义比较器并在 Guava 库中使用 Ordering,如下所示:
public static class SupportedAccountsComparator implements Comparator<AccountType> {
Ordering<String> ordering = Ordering.explicit(ImmutableList.of("rrsp", "tfsa"));
@Override
public int compare(AccountType o1, AccountType o2) {
return ordering.compare(o1.type, o2.type);
}
}
但它抛出异常,因为显式排序不支持不在您提供的列表中的其他项目,有没有办法进行部分显式排序?类似于:
Ordering.explicit(ImmutableList.of("rrsp", "tfsa")).anythingElseWhatever();
你不需要 Guava,你需要的一切都在集合中 API。
假设 AccountType
实现 Comparable
,您可以只提供 Comparator
returns "tfsa"
和 "rrsp"
的最小值,但是将其余排序留给 AccountType
的默认比较器:
Comparator<AccountType> comparator = (o1, o2) -> {
if(Objects.equals(o1.type, "rrsp")) return -1;
else if(Objects.equals(o2.type, "rrsp")) return 1;
else if(Objects.equals(o1.type, "tfsa")) return -1;
else if(Objects.equals(o2.type, "tfsa")) return 1;
else return o1.compareTo(o2);
};
accountTypes.sort(comparator);
如果您不想对其他项目进行排序,只需提供一个始终 returns 0 的默认比较器。
这是一个 Comparator
解决方案,它使用 List
字符串来表示您的排序顺序。只需更改 sortOrder
列表中字符串的顺序即可更改排序顺序。
Comparator<AccountType> accountTypeComparator = (at1, at2) -> {
List<String> sortOrder = Arrays.asList(
"rrsp",
"tfsa",
"third"
);
int i1 = sortOrder.contains(at1.type) ? sortOrder.indexOf(at1.type) : sortOrder.size();
int i2 = sortOrder.contains(at2.type) ? sortOrder.indexOf(at2.type) : sortOrder.size();
return i1 - i2;
};
accountTypes.sort(accountTypeComparator);
我需要以自定义方式订购列表,我正在研究正确的方式并找到番石榴的订购 api 但问题是我订购的列表并不总是如此一样,我只需要 2 个字段位于列表的顶部,例如我有这个:
List<AccountType> accountTypes = new ArrayList<>();
AccountType accountType = new AccountType();
accountType.type = "tfsa";
AccountType accountType2 = new AccountType();
accountType2.type = "rrsp";
AccountType accountType3 = new AccountType();
accountType3.type = "personal";
accountTypes.add(accountType3);
accountTypes.add(accountType2);
accountTypes.add(accountType);
//The order I might have is : ["personal", "rrsp", "tfsa"]
//The order I need is first "rrsp" then "tfsa" then anything else
我尝试使用自定义比较器并在 Guava 库中使用 Ordering,如下所示:
public static class SupportedAccountsComparator implements Comparator<AccountType> {
Ordering<String> ordering = Ordering.explicit(ImmutableList.of("rrsp", "tfsa"));
@Override
public int compare(AccountType o1, AccountType o2) {
return ordering.compare(o1.type, o2.type);
}
}
但它抛出异常,因为显式排序不支持不在您提供的列表中的其他项目,有没有办法进行部分显式排序?类似于:
Ordering.explicit(ImmutableList.of("rrsp", "tfsa")).anythingElseWhatever();
你不需要 Guava,你需要的一切都在集合中 API。
假设 AccountType
实现 Comparable
,您可以只提供 Comparator
returns "tfsa"
和 "rrsp"
的最小值,但是将其余排序留给 AccountType
的默认比较器:
Comparator<AccountType> comparator = (o1, o2) -> {
if(Objects.equals(o1.type, "rrsp")) return -1;
else if(Objects.equals(o2.type, "rrsp")) return 1;
else if(Objects.equals(o1.type, "tfsa")) return -1;
else if(Objects.equals(o2.type, "tfsa")) return 1;
else return o1.compareTo(o2);
};
accountTypes.sort(comparator);
如果您不想对其他项目进行排序,只需提供一个始终 returns 0 的默认比较器。
这是一个 Comparator
解决方案,它使用 List
字符串来表示您的排序顺序。只需更改 sortOrder
列表中字符串的顺序即可更改排序顺序。
Comparator<AccountType> accountTypeComparator = (at1, at2) -> {
List<String> sortOrder = Arrays.asList(
"rrsp",
"tfsa",
"third"
);
int i1 = sortOrder.contains(at1.type) ? sortOrder.indexOf(at1.type) : sortOrder.size();
int i2 = sortOrder.contains(at2.type) ? sortOrder.indexOf(at2.type) : sortOrder.size();
return i1 - i2;
};
accountTypes.sort(accountTypeComparator);