English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Lambda выражения, также известные как closures, являются одной из самых важных новых функций, которые推动了 выпуск Java 8.
Lambda позволяет передавать функцию в качестве параметра метода (функция передается в метод как параметр).
Использование lambda выражений делает код более кратким и компактным.
Синтаксис lambda выражений выглядит следующим образом:
(parameters) -> expression или (parameters) -> { statements; }
Вот важные характеристики lambda выражений:
Дополнительное указание типа:Тип параметра не нужно указывать, компилятор может определить его значение автоматически.
Дополнительные скобки round parentheses:При одном параметре не нужно определять скобки round parentheses, но при нескольких параметрах они необходимы.
Дополнительные скобки curly braces:Если тело выражения содержит только одно предложение, использование скобок curly braces не требуется.
Дополнительный ключ return:Если тело выражения содержит только один выражение, компилятор автоматически возвращает его значение, и скобки curly braces нужны для указания, что выражение возвращает числовое значение.
Пример простого выражения lambda:
// 1. Не требует параметров, возвращаемое значение 5 () -> 5 // 2. Получение одного параметра (типа числа) и возвращение его удвоенной величины x -> 2 * x // 3. Получение двух параметров (чисел) и возвращение их разности (x, y) -> x – y // 4. Получение двух целых чисел и возвращение их суммы (int x, int y) -> x + y // 5. Принимает объект string и выводит его в консоль, не возвращая никакого значения (похоже, это return void) (String s) -> System.out.print(s)
В файле Java8Tester.java введите следующий код:
public class Java8Tester { public static void main(String args[]){ Java8Tester tester = new Java8Tester(); // 类型声明 MathOperation addition = (int a, int b) -> a + b; // 不用类型声明 MathOperation subtraction = (a, b) -> a - b; // 大括号中的返回语句 MathOperation multiplication = (int a, int b) -> { return a * b; }; // 没有大括号及返回语句 MathOperation division = (int a, int b) -> a / b; System.out.println("10 + 5 = " + tester.operate(10, 5, addition)); System.out.println("10 - 5 = " + tester.operate(10, 5, subtraction)); System.out.println("10 x 5 = " + tester.operate(10, 5, multiplication)); System.out.println("10 / 5 = " + tester.operate(10, 5, division)); // 不用括号 GreetingService greetService1 = message -> System.out.println("Hello " + message); // 用括号 GreetingService greetService2 = (message) -> System.out.println("Hello " + message); greetService1.sayMessage("w3codebox"); greetService2.sayMessage("Google"); } interface MathOperation { int operation(int a, int b); } interface GreetingService { void sayMessage(String message); } private int operate(int a, int b, MathOperation mathOperation){ return mathOperation.operation(a, b); } }
Исполнение вышеуказанного скрипта выводит результат:
$ javac Java8Tester.java $ java Java8Tester 10 + 5 = 15 10 - 5 = 5 10 x 5 = 50 10 / 5 = 2 Привет w3codebox Привет Google
При использовании выражений lambda необходимо учитывать следующие два момента:
Выражения lambda主要用于 определение методов, выполняемых inline, например, простых метод-интерфейсов. В данном примере мы используем различные типы выражений lambda для определения методов интерфейса MathOperation. Затем мы определяем выполнение sayMessage.
Выражения lambda избегают необходимости использования анонимных методов и предоставляют Java простую, но мощную функциональную программирование.
Выражения lambda могут ссылаться только на локальные переменные, помеченные как final, что означает, что их нельзя изменять внутри lambda, в противном случае возникнет ошибка компиляции.
В файле Java8Tester.java введите следующий код:
public class Java8Tester { final static String salutation = "Hello! "; public static void main(String args[]){ GreetingService greetService1 = message -> System.out.println(salutation + message); greetService1.sayMessage("w3codebox"); } interface GreetingService { void sayMessage(String message); } }
Исполнение вышеуказанного скрипта выводит результат:
$ javac Java8Tester.java $ java Java8Tester Привет! w3codebox
Мы также можем напрямую обращаться к локальным переменным внешнего выражения lambda:
public class Java8Tester { public static void main(String args[]) { final int num = 1; Converter<Integer, String> s = (param) -> System.out.println(String.valueOf(param + num)); s.convert(2); // результат вывода - 3 } public interface Converter<T1, T2> { void convert(int i); } }
Локальные переменные выражений lambda могут не объявляться как final, но они должны быть не изменяемыми после них (именно это и означает隐性 final)
int num = 1; Converter<Integer, String> s = (param) -> System.out.println(String.valueOf(param + num)); s.convert(2); num = 5; // информация об ошибке: локальная переменная num определена в окружающем масштабе должна быть final или эффективно final
В Lambda-выражениях не разрешается声明 параметр с именем, которое совпадает с именем локальной переменной или параметра.
String first = ""; Comparator<String> comparator = (first, second) -> Integer.compare(first.length(), second.length()); // компиляция выйдет ошибку