Вы спросили, что такое param
и можно ли его искать. Вы также спросили о «форме» лямбда-выражения (почему круглые скобки присутствуют или нет). Мой ответ ниже отвечает на эти вопросы.
Поиск текста param
обычно не работает, так как текст param
является произвольным ... вы можете заменить его на p
или даже arbitraryName
и как пока имя справа от ->
в лямбда-выражении изменится на то же значение, код все равно должен работать.
Вы можете думать о param
как об имени, присвоенном «переданному» параметр. В объявлении метода ниже есть два параметра (param
и anotherParam
).
public void myPrint(String param, String anotherParam) {
System.out.println(param+", "+anotherParam);
}
Лямбда-выражение похоже на объявление метода (как указано выше), но ненужный текст можно удалить в синтаксисе лямбда-выражения. Если приведенное выше МОЖЕТ быть преобразовано в лямбда-выражение, оно будет выглядеть следующим образом:
(String param, String anotherParam) -> { System.out.println(param+", "+anotherParam); }
Обратите внимание, насколько лямбда-выражение похоже на объявление метода. Также обратите внимание, что текст «myPrint» не отображается в приведенном выше тексте. Лямбда-выражение можно рассматривать как объявление "безымянного" метода. В Java лямбда-выражение предоставляет код для реализации SingleAbstractMethod (SAM) в интерфейсе, в котором определен только один абстрактный метод. Предполагая, что у вас есть интерфейс с «MyPrint», определенным как имя SAM, тогда «MyPrint» не требуется (это единственный абстрактный метод в интерфейсе). Лямбда-выражения работают, потому что интерфейс SAM является «функциональным интерфейсом», а лямбда-выражения реализуют SAM в функциональном интерфейсе. В лямбда-выражении имя метода, который вы реализуете, ВСЕГДА не требуется. Это одна из причин, по которой лямбда-выражения трудно понять, поскольку вы обычно понимаете метод по его имени (в некоторой степени), и вы хотели бы искать по имени метода, которое реализует лямбда-выражение, но это имя не отображается в лямбда-код.
Приведенный выше код также может быть записан как ...
(param, anotherParam) -> { System.out.println(param+", "+anotherParam); }
, если система Java Type может определить типы параметров (в данном случае String
) для себя. Опять же, имена param
и anotherParam
произвольны, но их типы - нет. Они определяются SAM в функциональном интерфейсе, который вы реализуете с помощью лямбда. Другая причина, по которой лямбда-выражения трудны для понимания, заключается в том, что тип параметра (ов) часто интересен ... но он часто опускается в лямбда-выражении, поскольку Java не всегда требуется.
If SAM был нужен только один параметр, лямбда-выражение могло быть записано следующим образом:
(String param) -> { System.out.println(param); }
, или если "String" может быть определен как Java
(param) -> { System.out.println(param); }
или даже ()
не нужны в этой последней версии
param -> { System.out.println(param); }
Есть и другие упрощения. В некоторых случаях {}
справа от ->
можно удалить, если это только один оператор или выражение.
Если в реализуемой SAM нет параметров, то код () ->
используется, где ()
означает отсутствие параметров.
Последнее, что я упомяну, что трудно понять в лямбда-выражении, - это большое количество упрощений синтаксиса, которые можно сделать (см. Все выше). Кажется, это основная причина вашего недоразумения.
Итог: лямбда-выражение можно рассматривать как объявление безымянного метода, в котором вы переопределяете SAM в функциональном интерфейсе. Левая часть ->
- это объявления параметров ... типы параметров и даже ()
не всегда нужны. Правая часть ->
- это тело метода, а в некоторых случаях {}
не нужны.
Ключом к пониманию лямбда-выражения является понимание синтаксиса (все вышеперечисленные формы) и определение и понимание реализуемого функционального интерфейса и SAM. К сожалению, ни функциональный интерфейс, ни имя SAM не отображаются в самом синтаксисе лямбда-выражения ... он упрощен, поскольку в нем нет необходимости!