使用lambdas而不是显式类

inv*_*bl3 1 java lambda comparator

我有程序使用显式类来排序值:

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);
...
Run Code Online (Sandbox Code Playgroud)

完整代码

得到结果:

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
Run Code Online (Sandbox Code Playgroud)

然后,我正在尝试添加lambdas而不是显式类,如:

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(' '))));
Run Code Online (Sandbox Code Playgroud)

完整代码

结果是:

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
Run Code Online (Sandbox Code Playgroud)

但我没有得到完整的名单(没有拉尔夫史密斯:-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);
    ...
Run Code Online (Sandbox Code Playgroud)

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);
    ...
Run Code Online (Sandbox Code Playgroud)

Rad*_*def 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;
}
Run Code Online (Sandbox Code Playgroud)

(另请参阅OpenJDK源代码.)

或者您可以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));
Run Code Online (Sandbox Code Playgroud)

但是,编写这样的比较器的最简单方法可能就是这样,使用comparing(Function,Comparator):

Comparator.comparing(str -> str.substring(str.lastIndexOf(' ')),
                     String.CASE_INSENSITIVE_ORDER)
          .thenComparing(String.CASE_INSENSITIVE_ORDER)
Run Code Online (Sandbox Code Playgroud)

(另见String.CASE_INSENSITIVE_ORDER文档.)