Тело лямбда-выражений обычно состоят из единственного выражения. Такая разновидность тел называется телом выражения, а лямбда-выражения с телом выражения иногда еще называют одиночными.
В теле выражения код, указываемый в правой части лямбда-оператора, должен состоять из одного выражения.
Несмотря на все удобство одиночных лямбда-выражений, иногда в них требуется вычислять не одно выражение.
Для подобных случаев в Java предусмотрена вторая разновидность лямбда-выражений, где код, указываемый в правой части лямбда-оператора, может состоять из нескольких операторов. Такие лямбда-выражения называются блочными, а их тело телом блока.
Блочное лямбда-выражение расширяет те виды операций, которые могут выполняться в лямбда-выражении, поскольку оно допускает в своем теле наличие нескольких операторов.
Например, в блочном лямбда-выражении можно объявлять переменные, организовывать циклы, указывать операторы выбора if и switch, создавать вложенные блоки и т.д.
Создать блочное лямбда-выражение совсем не трудно. Для этого достаточно заключить тело выражения в фигурные скобки таким же образом, как и любой другой блок кода.
Кроме наличия в теле выражения нескольких операторов, блочные лямбда выражения применяются точно так же, как и одиночные лямбда-выражения.
Однако для возврата значения из блочных лямбда-выражений нужно явно указывать оператор return. Это нужно делать потому, что тело блочного лямбда-выражения не представляет одиночное выражение.
Ниже приведен пример программы, в котором блочное лямбда-выражение применяется для вычисления и возврата факториала целочисленного значения.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
// Блочное лямбда-выражение, вычисляющее // факториал целочисленного значения interface NumericFunc { int func(int n); } class BlockLambdaDemo { public static void main(String args[]) { // Это блочное лямбда-выражение вычисляет // факториал целочисленного значения NumericFunc factorial = (n) -> { int result = 1; for(int i = 1; i <=n; i++) { result = i * result; } return result; }; System.out.println("Факториал числа 6 равен " + factorial.func(6)); System.out.println("Факториал числа 8 равен " + factorial.func(8)); System.out.println("Факториал числа 10 равен " + factorial.func(10)); } } |
Ниже приведен результат выполнения данной программы:
1 2 3 4 5 6 |
pro-java.ru@admin:~$ javac lambd.java pro-java.ru@admin:~$ java BlockLambdaDemo Факториал числа 6 равен 720 Факториал числа 8 равен 40320 Факториал числа 10 равен 3628800 pro-java.ru@admin:~$ |
В данном примере программы обратите внимание на то, что в блочном лямбда выражении объявляется переменная result, организуется цикл for и указывается оператор return.
Все эти действия вполне допустимы в теле блочного лямбда выражения. По существу, тело блока такого выражения аналогично телу метода.
Следует также иметь в виду, что когда в лямбда-выражении оказывается оператор return, он просто вызывает возврат из самого лямбда-выражения , но не из объемлющего его метода.
Ниже приведен еще один пример блочного лямбда-выражения. В данном примере программы изменяется на обратный порядок следования символов в строке.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
// Блочное выражение, изменяющее на обратный // порядок следования символов в строке interface StringFunc { String func(String n); } class BlockLambdaDemoString { public static void main(String args[]) { // Это блочное выражение изменяет на обратный // порядок следованя символов в строек StringFunc reverse = (str) -> { String result = ""; int i; for(i = str.length() - 1; i >=0; i--) { result += str.charAt(i); } return result; }; System.out.println("Лямбда обращается на " + reverse.func("Лямбда")); System.out.println("Выражение обращается на " + reverse.func("Выражение")); } } |
Ниже приведен результат выполнения данной программы.
1 2 3 4 5 |
pro-java.ru@admin:~$ javac lambdstr.java pro-java.ru@admin:~$ java BlockLambdaDemoString Лямбда обращается на адбмяЛ Выражение обращается на еинежарыВ pro-java.ru@admin:~$ |
В данном примере программы в функциональном интерфейсе StringFunc объявляется метод func() принимающий параметр типа String и возвращающий значение типа String.
Следовательно, в лямбда-выражении reverse тип параметра str должен быть выведен как String. Обратите внимание на то, что метод charAt() вызывается для параметра str как для объекта.
И это вполне допустимо, поскольку этот параметр имеет тип String благодаря выведению типов.