• Java Lambda Expression Basic


    Syntax of Lambda Expressions

    A lambda expression consists of the following:

    • A comma-separated list of formal parameters enclosed in parentheses. The CheckPerson.test method contains one parameter, p, which represents an instance of the Person class.

      Note: You can omit the data type of the parameters in a lambda expression. In addition, you can omit the parentheses if there is only one parameter. For example, the following lambda expression is also valid:

      p -> p.getGender() == Person.Sex.MALE 
          && p.getAge() >= 18
          && p.getAge() <= 25
      
    • The arrow token, ->

    • A body, which consists of a single expression or a statement block. This example uses the following expression:

      p.getGender() == Person.Sex.MALE 
          && p.getAge() >= 18
          && p.getAge() <= 25
      

      If you specify a single expression, then the Java runtime evaluates the expression and then returns its value. Alternatively, you can use a return statement:

      p -> {
          return p.getGender() == Person.Sex.MALE
              && p.getAge() >= 18
              && p.getAge() <= 25;
      }
      

      A return statement is not an expression; in a lambda expression, you must enclose statements in braces ({}). However, you do not have to enclose a void method invocation in braces. For example, the following is a valid lambda expression:

      email -> System.out.println(email)
      

    Note that a lambda expression looks a lot like a method declaration; you can consider lambda expressions as anonymous methods—methods without a name.

    The following example, Calculator, is an example of lambda expressions that take more than one formal parameter:

    public class Calculator {
      
        interface IntegerMath {
            int operation(int a, int b);   
        }
      
        public int operateBinary(int a, int b, IntegerMath op) {
            return op.operation(a, b);
        }
     
        public static void main(String... args) {
        
            Calculator myApp = new Calculator();
            IntegerMath addition = (a, b) -> a + b;
            IntegerMath subtraction = (a, b) -> a - b;
            System.out.println("40 + 2 = " +
                myApp.operateBinary(40, 2, addition));
            System.out.println("20 - 10 = " +
                myApp.operateBinary(20, 10, subtraction));    
        }
    }
    

    The method operateBinary performs a mathematical operation on two integer operands. The operation itself is specified by an instance of IntegerMath. The example defines two operations with lambda expressions, addition and subtraction. The example prints the following:

    40 + 2 = 42
    20 - 10 = 10
    

    Accessing Local Variables of the Enclosing Scope

    Like local and anonymous classes, lambda expressions can capture variables; they have the same access to local variables of the enclosing scope. However, unlike local and anonymous classes, lambda expressions do not have any shadowing issues (see Shadowing for more information). Lambda expressions are lexically scoped. This means that they do not inherit any names from a supertype or introduce a new level of scoping. Declarations in a lambda expression are interpreted just as they are in the enclosing environment. The following example, LambdaScopeTest, demonstrates this:

    package com.oracle.docs;
    
    import java.util.function.Consumer;
    
    public class LambdaScopeTest {
    
        public int x = 0;
    
        class FirstLevel {
    
            public int x = 1;
    
            void methodInFirstLevel(int x) {
                
                // The following statement causes the compiler to generate
                // the error "local variables referenced from a lambda expression
                // must be final or effectively final" in statement A:
                // 以下语句导致编译器在语句A中生成错误
                // 从lambda 表达式引用的本地变量必须是最终变量或实际上的最终变量
                
                // x = 99;
                
                Consumer<Integer> myConsumer = (y) -> 
                {
                    System.out.println("x = " + x); // Statement A
                    System.out.println("y = " + y);
                    System.out.println("this.x = " + this.x);
                    System.out.println("LambdaScopeTest.this.x = " +
                        LambdaScopeTest.this.x);
                };
    
                myConsumer.accept(x);
    
            }
        }
    
        public static void main(String... args) {
            LambdaScopeTest st = new LambdaScopeTest();
            LambdaScopeTest.FirstLevel fl = st.new FirstLevel();
            fl.methodInFirstLevel(23);
        }
    }
    

    This example generates the following output:

    x = 23
    y = 23
    this.x = 1
    LambdaScopeTest.this.x = 0
    

    Java Lambda Expression With No Parameter

    package com.beginnersbook;
    
    @FunctionalInterface
    interface MyFunctionalInterface {
    
    	//A method with no parameter
        public String sayHello();
    }
    
    public class NoParameterExample {
    
       public static void main(String args[]) {
           
            // lambda expression
        	MyFunctionalInterface msg = () -> {
        		return "Hello Lambda Expression";
        	};
           
            System.out.println(msg.sayHello());
        }
    }
    

    Java Lambda Expression With Single Parameter

    package com.beginnersbook;
    
    @FunctionalInterface
    interface MyFunctionalInterface {
    
    	//A method with single parameter
        public int incrementByFive(int a);
    }
    public class SingleParameterExample {
    
       public static void main(String args[]) {
            // lambda expression with single parameter num
        	MyFunctionalInterface f = (num) -> num+5;
            System.out.println(f.incrementByFive(22));
        }
    }
    

    Java Lambda Expression With Multiple Parameters

    package com.beginnersbook;
    
    interface StringConcat {
    
        public String sconcat(String a, String b);
    }
    public class Example {
    
       public static void main(String args[]) {
            // lambda expression with multiple arguments
        	StringConcat s = (str1, str2) -> str1 + str2;
            System.out.println("Result: "+s.sconcat("Hello ", "World"));
        }
    }
    

    Following are the important characteristics of a lambda expression.

    • Optional type declaration − No need to declare the type of a parameter. The compiler can inference the same from the value of the parameter.

      可选的类型声明 - 无需声明参数的类型。编译器可以根据参数的值进行推断。

    • Optional parenthesis around parameter − No need to declare a single parameter in parenthesis. For multiple parameters, parentheses are required.

      参数周围的可选括号 - 无需在括号中声明单个参数。对于多个参数,需要括号。

    • Optional curly braces − No need to use curly braces in expression body if the body contains a single statement.

      可选花括号 - 如果正文包含单个语句,则无需在表达式正文中是用花括号

    • Optional return keyword − The compiler automatically returns the value if the body has a single expression to return the value. Curly braces are required to indicate that expression returns a value.

      可选return关键字 - 如果主体具有用于返回该值的单个表达式,则编译器将自动返回该值。需要大括号表示表达式返回一个值。

      package com.tutorialspoint;
      
      public class Java8LambdaExpression {
      
         public static void main(String args[]) {
             
            Java8LambdaExpression tester = new Java8LambdaExpression();
      		
            //with type declaration
            MathOperation addition = (int a, int b) -> a + b;
      		
            //with out type declaration
            MathOperation subtraction = (a, b) -> a - b;
      		
            //with return statement along with curly braces
            MathOperation multiplication = (int a, int b) -> { return a * b; };
      		
            //without return statement and without curly braces
            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));
      		
            //without parenthesis
            GreetingService greetService1 = message ->
            System.out.println("Hello " + message);
      		
            //with parenthesis
            GreetingService greetService2 = (message) ->
            System.out.println("Hello " + message);
      		
            greetService1.sayMessage("Mahesh");
            greetService2.sayMessage("Suresh");
         }
      	
         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);
         }
      }
      

      It should produce the following output

      10 + 5 = 15
      10 - 5 = 5
      10 x 5 = 50
      10 / 5 = 2
      Hello Mahesh
      Hello Suresh
      

      Following are the important points to be considered in the above example.

      • Lambda expressions are used primarily to define inline implementation of a functional interface, i.e., an interface with a single method only. In the above example, we've used various types of lambda expressions to define the operation method of MathOperation interface. Then we have defined the implementation of sayMessage of GreetingService.

        Lambda表达式主要用于定义功能接口的内联实现,即仅具有单个方法的接口。在上面的示例中,我们使用了各种类型的lambda表达式来定义MathOperation接口的操作方法。然后,我们定义了GreetingService的sayMessage的实现。

      • Lambda expression eliminates the need of anonymous class and gives a very simple yet powerful functional programming capability to Java.

        Lambda表达式消除了对匿名类的需求,并为Java提供了非常简单而强大的功能编程能力。

      Scope

      Using lambda expression, you can refer to any final variable or effectively final variable (which is assigned only once). Lambda expression throws a compilation error, if a variable is assigned a value the second time.使用lambda表达式,您可以引用任何最终变量或有效地最终变量。如果第二次为变量赋值,则Lambda表达式将引发编译错误。

      Scope Example

      public class Java8LambdaExpressionScope {
      
         final static String salutation = "Hello! ";
         
         public static void main(String args[]) {
            GreetingService greetService1 = message -> 
            System.out.println(salutation + message);
            greetService1.sayMessage("Mahesh");
         }
      	
         interface GreetingService {
            void sayMessage(String message);
         }
      }
      

      Output

      Hello! Mahesh
      
  • 相关阅读:
    工业以太网的现状与发展
    软件开发的7大原则
    white-space
    vue使用better-scroll做轮播图(1.X版本 比较简单)
    windows 查看端口占用
    使用通知notication pendingIntent 传递参数
    fragment 创建optionsmenu
    android viewmodel 带参数
    LifecycleObserver 生命周期检测
    过河问题
  • 原文地址:https://www.cnblogs.com/PrimerPlus/p/13150134.html
Copyright © 2020-2023  润新知