zoukankan      html  css  js  c++  java
  • Lambda 表达式

    Lambda 表达式是一种匿名函数,简单地说,它是没有声明的方法,也即没有访问修饰符、返回值声明和名字

    Lambda 表达式的结构

    让我们了解一下 Lambda 表达式的结构。

    • 一个 Lambda 表达式可以有零个或多个参数
    • 参数的类型既可以明确声明,也可以根据上下文来推断。例如:(int a)(a)效果相同
    • 所有参数需包含在圆括号内,参数之间用逗号相隔。例如:(a, b) 或 (int a, int b) 或 (String a, int b, float c)
    • 空圆括号代表参数集为空。例如:() -> 42
    • 当只有一个参数,且其类型可推导时,圆括号()可省略。例如:a -> return a*a
    • Lambda 表达式的主体可包含零条或多条语句
    • 如果 Lambda 表达式的主体只有一条语句,花括号{}可省略。匿名函数的返回类型与该主体表达式一致
    • 如果 Lambda 表达式的主体包含一条以上语句,则表达式必须包含在花括号{}中(形成代码块)。匿名函数的返回类型与代码块的返回类型一致,若没有返回则为空

    例子:

    @FunctionalInterface
    public interface WorkerInterface {
        public void doSomeWork();
    }
    

      

    public class WorkerInterfaceTest {
        public static  void  execute(WorkerInterface work){
            work.doSomeWork();
        }
    
        public static void main(String[] args) {
            execute(new WorkerInterface() {
                @Override
                public void doSomeWork() {
                    System.out.println("Worker invoked using Anonymous class");
                }
            });
            WorkerInterface w = () -> System.out.println("haha");
            execute(w);
            execute( () -> System.out.println("Worker invoked using Lambda expression") );
        }
    }
    

      

    结果
    Worker invoked using Anonymous class
    haha
    Worker invoked using Lambda expression
    

      以下代码的作用是打印出给定数组中的所有元素。注意,使用 Lambda 表达式的方法不止一种。在下面的例子中,我们先是用常用的箭头语法创建 Lambda 表达式,之后,使用 Java 8 全新的双冒号(::)操作符将一个常规方法转化为 Lambda 表达式:

    List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
            list.forEach(n -> System.out.println(n));
    
    
            //or we can use :: double colon operator in Java 8
            list.forEach(System.out::println);
    

      在下面的例子中,我们使用断言(Predicate)函数式接口创建一个测试,并打印所有通过测试的元素,这样,你就可以使用 Lambda 表达式规定一些逻辑,并以此为基础有所作为:

    public class Main {
    
    public static void main(String [] a)  {
    
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
    
        System.out.println("Print all numbers:");
        evaluate(list, (n)->true);
    
        System.out.println("Print no numbers:");
        evaluate(list, (n)->false);
    
        System.out.println("Print even numbers:");
        evaluate(list, (n)-> n%2 == 0 );
    
        System.out.println("Print odd numbers:");
        evaluate(list, (n)-> n%2 == 1 );
    
        System.out.println("Print numbers greater than 5:");
        evaluate(list, (n)-> n > 5 );
    
    }
    
    public static void evaluate(List<Integer> list, Predicate<Integer> predicate) {
        for(Integer n: list)  {
            if(predicate.test(n)) {
                System.out.println(n + " ");
            }
        }
    }
    
    }   
    输出:
    
    Print all numbers: 1 2 3 4 5 6 7 
    Print no numbers: 
    Print even numbers: 2 4 6 
    Print odd numbers: 1 3 5 7 
    Print numbers greater than 5: 6 7
    

      下面的例子使用 Lambda 表达式打印数值中每个元素的平方,注意我们使用了 .stream() 方法将常规数组转化为流。Java 8 增加了一些超棒的流 APIs。java.util.stream.Stream 接口包含许多有用的方法,能结合 Lambda 表达式产生神奇的效果。我们将 Lambda 表达式 x -> x*x 传给 map() 方法,该方法会作用于流中的所有元素。之后,我们使用 forEach 方法打印数据中的所有元素:

    //Old way:
    List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
    for(Integer n : list) {
        int x = n * n;
        System.out.println(x);
    }
    
    //New way:
    List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
    list.stream().map((x) -> x*x).forEach(System.out::println);
    

      下面的例子会计算给定数值中每个元素平方后的总和。请注意,Lambda 表达式只用一条语句就能达到此功能,这也是 MapReduce 的一个初级例子。我们使用 map() 给每个元素求平方,再使用 reduce() 将所有元素计入一个数值:

    //Old way:
    List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
    int sum = 0;
    for(Integer n : list) {
        int x = n * n;
        sum = sum + x;
    }
    System.out.println(sum);
    
    //New way:
    List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
    int sum = list.stream().map(x -> x*x).reduce((x,y) -> x + y).get();
    System.out.println(sum);
    

      

    Lambda 表达式与匿名类的区别

    使用匿名类与 Lambda 表达式的一大区别在于关键词的使用。对于匿名类,关键词 this 解读为匿名类,而对于 Lambda 表达式,关键词 this 解读为写就 Lambda 的外部类。

    Lambda 表达式与匿名类的另一不同在于两者的编译方法。Java 编译器编译 Lambda 表达式并将他们转化为类里面的私有函数,它使用 Java 7 中新加的 invokedynamic 指令动态绑定该方法

  • 相关阅读:
    jquery animate()方法 语法
    jquery unload方法 语法
    jquery undelegate()方法 语法
    jquery unbind()方法 语法
    jquery trigger() 方法 语法
    jquery toggle()方法 语法
    jquery change() 函数 语法
    jquery blur()函数 语法
    jquery bind()方法 语法
    jquery checked选择器 语法
  • 原文地址:https://www.cnblogs.com/qull/p/7016043.html
Copyright © 2011-2022 走看看