如何将以下比较器翻译成Comparator.comparing?

How to translate following comparator into Comparator.comparing?

我的问题可能不清楚,让我举个例子:

Arrays.sort(arr, new Comparator<String>(){
    public int compare(String a, String b){
        return (b + a).compareTo(a + b);
    }
});

我想使用Comparator.comparing。我尝试了以下方法:

Arrays.sort(arr, Comparator.comparing((a, b) -> (b + a).compareTo((String)a + b)));

我收到一个错误 - return 错误地输入了 lamdba 表达式。如何解决这个问题?

Comparator.comparing 方法需要类型 FunctionkeyExtractor。你只需要一个 lambda 来实现这里的 Comparator<String> 接口:

Arrays.sort(arr, (a, b) -> (b + a).compareTo(a + b));

不可能将其转换为对比较的调用,因为它不是有效的比较器:它不满足比较器协定,您永远不应将其用作比较器。

为了证明这一点,Comparator 会将每个字符串都比较为等于“”,但并非每个字符串都彼此相等。这违反了传递性 属性.

如前所述,您的匿名 class 实现可以缩短为 lambda 表达式:

Arrays.sort(arr, (a, b) -> (b + a).compareTo(a + b));

如果您坚持使用Comparator.comparing(),请记住它有一些特定参数不适合您的排序问题。

  • Comparator.comparing(keyExtractor) returns a specified Comparator for certain key based on the natural way of comparison (Comparator.naturalOrder)。你的方法没有说比较什么,而是如何比较。
  • Comparator.comparing(keyExtractor, keyComparator) 看起来好一点,因为您可以指定 如何 使用 keyComparator 比较指定的键。您可以使用您的比较逻辑并得出结论:

    Arrays.sort(arr, Comparator.comparing(
        Function.identity(),                  // keyExtractor, WHAT is compared
        (a, b) -> (b + a).compareTo(a + b))); // keyComparator, HOW is it compared
    

    这是一个使用 Comparator.comparing 的解决方案,它使用 keyExtractor Function.identity() 返回输入(与 str -> str lambda 表达式相同),因为您仍然想要比较字符串,但以自定义 Comparator 指定的不同方式,因此根据需要对数组进行排序的唯一正确方法是省略 keyExtractor:

    的简化版本
    Arrays.sort(arr, (a, b) -> (b + a).compareTo(a + b));
    

    ...这就是我们的起点。