我有一个使用显式类对值进行排序的程序:
class CompLastNames implements Comparator<String> {
public int compare(String aStr, String bStr) {
int i, j;
i = aStr.lastIndexOf(' ');
j = bStr.lastIndexOf(' ');
return aStr.substring(i).compareToIgnoreCase(bStr.substring(j));
}
}
class CompThenByFirstName implements Comparator<String> {
public int compare(String aStr, String bStr) {
int i, j;
return aStr.compareToIgnoreCase(bStr);
}
}
public class TreeMapDemo2A {
public static void main(String[] args) {
CompLastNames compLN = new CompLastNames();
Comparator<String> compLastThenFirst =
compLN.thenComparing(new CompThenByFirstName());
TreeMap<String, Double> tm =
new TreeMap<String, Double>(compLastThenFirst);
...
得到结果:
Jane Baker: 1378.0
John Doe: 3434.34
Ralph Smith: -19.08
Tom Smith: 123.22
Tod Hull: 99.22
The new account balance of John Doe: 4434.34
然后,我尝试添加lambda而不是像这样的显式类:
Comparator<String> compLastThenFirst =
((aStr, bStr) -> aStr.compareToIgnoreCase(bStr));
TreeMap<String, Double> tm =
new TreeMap<String, Double>((aStr, bStr) -> aStr.substring(aStr.lastIndexOf(' ')).compareToIgnoreCase(bStr.substring(bStr.lastIndexOf(' '))));
结果是:
Jane Baker: 1378.0
John Doe: 3434.34
Tom Smith: -19.08
Tod Hull: 99.22
The new account balance of John Doe: 4434.34
但是我没有完整列表(没有Ralph Smith:-19.08)。 有谁知道怎么写?谢谢。
UPD:
1)
Comparator<String> compLastThenFirst =
((Comparator<String>) (a, b) -> a.substring(a.lastIndexOf(' ')).compareToIgnoreCase(b.substring(b.lastIndexOf(' '))))
.thenComparing((a, b) -> a.compareToIgnoreCase(b));
TreeMap<String, Double> tm =
new TreeMap<String, Double>(compLastThenFirst);
...
2)
Comparator<String> compLN = (aStr, bStr) ->
aStr.substring(aStr.lastIndexOf(' '))
.compareToIgnoreCase(bStr.substring(bStr.lastIndexOf(' ')));
Comparator<String> compLastThenFirst =
compLN.thenComparing((aStr, bStr) -> aStr.compareToIgnoreCase(bStr));
TreeMap<String, Double> tm =
new TreeMap<String, Double>(compLastThenFirst);
...
答案 0 :(得分:5)
您将需要重新实现thenComparing(Comparator)
的作用:
(aStr, bStr) -> {
int compareResult =
aStr.substring(aStr.lastIndexOf(' '))
.compareToIgnoreCase(
bStr.substring(bStr.lastIndexOf(' '))
)
if (compareResult != 0)
compareResult = aStr.compareToIgnoreCase(bStr);
return compareResult;
}
(也see the OpenJDK source code。)
或者您可以通过分配一个临时变量来使用thenComparing
(如第一个示例中所示):
Comparator<String> compLN = (aStr, bStr) ->
aStr.substring(aStr.lastIndexOf(' '))
.compareToIgnoreCase(bStr.substring(bStr.lastIndexOf(' ')));
Comparator<String> compLastThenFirst =
compLN.thenComparing((aStr, bStr) -> aStr.compareToIgnoreCase(bStr));
但是,使用comparing(Function,Comparator)
编写这样的比较器的最简单方法可能是这样的:
Comparator.comparing(str -> str.substring(str.lastIndexOf(' ')),
String.CASE_INSENSITIVE_ORDER)
.thenComparing(String.CASE_INSENSITIVE_ORDER)
(另请参见String.CASE_INSENSITIVE_ORDER
文档。)
答案 1 :(得分:2)
正如@Sweeper在评论中提到的那样,您忘记了对Comparator#thenComparing
的呼叫。带有lambda表达式的相应代码为:
Comparator<String> compLastThenFirst =
((Comparator<String>) (a, b) -> a.substring(a.lastIndexOf(' ')).compareToIgnoreCase(b.substring(b.lastIndexOf(' '))))
.thenComparing((a, b) -> a.compareToIgnoreCase(b));