Java 为什么 Comparator.comparing 不适用于 String::toLowerCase 方法引用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22936972/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 19:24:22  来源:igfitidea点击:

Why Comparator.comparing doesn't work with String::toLowerCase method reference?

javacomparatorjava-8java-streammethod-reference

提问by loloof64

I am trying to sort an array of Strings by reverse order (ignoring case), without modifying it, and just printing it. So I am using Java8 stream. But I can't manage to do it.

我正在尝试按相反的顺序(忽略大小写)对字符串数组进行排序,而不修改它,而只是打印它。所以我使用的是 Java8 流。但我做不到。

Here is my attempt :

这是我的尝试:

package experimentations.chapter02;

import java.util.Arrays;
import java.util.Comparator;
import java.util.stream.Collectors;

public class StringStream {

    public static void main(String[] args) {
        sortStrings();
    }

    public static void sortStrings(){
        String[] stringsArray = "The quick brown fox has a dirty ladder".split("\s+");
        System.out.println(
                Arrays.stream(stringsArray)
                .sorted(Comparator.comparing(String::toLowerCase).reversed())
                .collect(Collectors.toList())
        );
    }

}

The problem here is that String::toLowerCaseis not accepted in the static method Comparator.comparing.

这里的问题是String::toLowerCase在静态方法中不被接受Comparator.comparing

Meanwhile, I managed to sort the array, but modifyingit:

同时,我设法对数组进行了排序,但对其进行了修改

public static void sortStrings(){
        String[] stringsArray = "The quick brown fox has a dirty ladder".split("\s+");
        System.out.println(
                Arrays.stream(stringsArray)
                .map(String::toLowerCase)
                .sorted(Comparator.reverseOrder())
                .collect(Collectors.toList())
        );
}

So, what is the simpliest workaround?

那么,最简​​单的解决方法是什么?

采纳答案by nosid

The problem is, that Java can not deduce the generic types for some complex expressions. The first statement works, whereas the second statement leads to a compile-time error:

问题是,Java 无法推导出某些复杂表达式的泛型类型。第一条语句有效,而第二条语句导致编译时错误:

Comparator<String> comparator = Comparator.comparing(String::toLowerCase);
Comparator<String> comparator = Comparator.comparing(String::toLowerCase).reversed();

There are several ways to solve the problem. Here are three of them:

有几种方法可以解决这个问题。以下是其中三个:

Store the intermediate Comparatorin a variable:

将中间Comparator存储在一个变量中:

Comparator<String> comparator = Comparator.comparing(String::toLowerCase);
System.out.println(
            Arrays.stream(stringsArray)
            .sorted(comparator.reversed())
            .collect(Collectors.toList()));

Use String.CASE_INSENSITIVE_ORDER:

使用String.CASE_INSENSITIVE_ORDER

System.out.println(
            Arrays.stream(stringsArray)
            .sorted(String.CASE_INSENSITIVE_ORDER.reversed())
            .collect(Collectors.toList()));

Add explicit type parameters:

添加显式类型参数:

System.out.println(
            Arrays.stream(stringsArray)
            .sorted(Comparator.<String,String>comparing(String::toLowerCase).reversed())
            .collect(Collectors.toList()));

回答by loloof64

I found the solution :

我找到了解决方案:

 .sorted((String e) -> e.toLowerCase) 

I think the problem with the syntax

我认为语法的问题

 .sorted(String::toLowerCase)

is that the compiler then expects to pass an Object to the instance method toLowerCase of String. So I need to make my own lambda method, without ignoring the type of the lambda parameter (String), otherwise the compiler still can't resolve it.

是编译器然后期望将一个 Object 传递给 String 的实例方法 toLowerCase。所以需要自己制作lambda方法,不能忽略lambda参数(String)的类型,否则编译器还是无法解析。