оператор конвейера карты, связанный с интерфейсом функции - PullRequest
1 голос
/ 23 марта 2020

Я не могу понять, почему выражение String::toUpperCase() прекрасно работает в потоке map конвейер . Когда я смотрю на этот пример здесь:

Stream.of("test1", "test2", "test3", "test4")
                .filter(s -> s.contains("r"))
                .map(s -> s + "map")
                .map(String::toUpperCase)
                .forEach(System.out::println);

Когда я смотрю на определение оператора карты, использованное в приведенном ниже примере map(Function<? super String, ? extends String> mapper), я вижу, что используется шаблон проектирования функции.

В этом примере .map(s -> s + "map") хорошо, так как я понимаю, что мы ищем Function, точнее R apply(T t);, это полностью то, что лямбда-выражение говорит s -> s + "map" здесь у нас есть функция с параметром s и она возвращает s + Строка "map" и соответствует этой спецификации c. T и R, они присутствуют.

С другой стороны, вторая map(String::toUpperCase), я не могу понять, почему выражение toUpperCase считается интерфейсом Function, я Следует отметить, что ядро ​​этой функции выглядит так:

public String toUpperCase() {
    return toUpperCase(Locale.getDefault());
}

, и мы ищем R apply(T t);, в этом методе нет параметра T toUpperCase? Почему этот работает?

Ответы [ 2 ]

4 голосов
/ 23 марта 2020

Что гораздо проще понять с точки зрения метода apply интерфейса Function, так это анонимное представление класса ссылки на метод String::toUpperCase. Это выглядит так -

new Function<String, String>() {
    @Override
    public String apply(String str) { // read as given a String return a String (uppercased)
        return str.toUpperCase();
    }
}

Строковые аргументы (str), предоставленные вышеописанному методу apply, являются аргументами из Stream после предыдущей операции map.

4 голосов
/ 23 марта 2020

Это называется ссылкой на метод, и это syntacti c сахар для лямбда-выражения. Другими словами, следующее:

String::toUpperCase

эквивалентно:

s -> s.toUpperCase()

Это метод, который принимает String s и возвращает String со всей буквой из s заглавными буквами, это Function<String, String>.

...