zoukankan      html  css  js  c++  java
  • Java lambda表达式

    lambda表达式是一个匿名函数,通俗解释是:可以传递的、在以后执行一次或多次的代码块。Java8中引入的特性。

    lambda表达式的语法

    形式:(参数)-> 表达式

    0.若表达式复杂,可以用大括号括起。{语句块}

    1.没有参数的情况:仍然需要提供空括号。

    ()->{for (int i = 100;i >= 0;i--) System.out.println(i);}

    2.如果可以推导出参数类型:可以忽略参数类型。

    Compertor<String> comp = (first,second) ->first.length()-scond.length();//参数类型必为字符串

    3.如果只有一个参数,可以推导出参数类型:可以省略小括号。

    4.无需指定lambda表达式的返回类型,自动由上下文推导得出。

    函数式接口

    对于只有一个抽象方法的接口,需要这种接口的对象时,可以提供一个lambda表达式。只有一个抽象方法的接口被称为函数式接口。

    如Array.sort方法需要提供一个数组和比较器(comparator)。比较器是实现了Comparator接口的实例对象。该接口只有一个方法。如普通实现:

    class LengthComparater implements Comparator<String>{
        public int compare(String first,String second){
            return first.length() - second.length();
        }
    }

    这样,就可以创建一个LengthComparater类传入Array.sort函数中。

    Array.sort(words,new LengthComparator())

    而用lambda表达式:

    Array.sort(words,(first,second)->first.length()-secong.length())

    这样做,对compare方法的调用会执行这个lambda表达式的体,它把lambda看做一个函数。这样做法效率要高;代码可读性也要好一些。

    方法引用

    使用双冒号(::)分隔方法和对象名来表示一个方法引用,与lambda表达式效果相同。有3种写法:

    object::instanceMethod(x,x,x...)   等价于(x,x,x...)->object.instanceMethod(x,x,x...)

    Class::staticMethod(x,x,x,....)          等价于(x,x,x...)->object.staticMethod(x,x,x...)

    Class::instanceMethod(x,y,z...)      等价于(x)->x.instanceMethod(y,z.....)  //第一个参数会成为方法的目标

    可以在方法引用中使用this和super参数

    构造器引用

    与方法引用类似,方法名为new。例如Person::new是Person构造器的一个引用。

    变量作用域

    lambda表达式可以捕获外围作用域中变量的值,但却有些限制。

    规则:lambda表达式中捕获的变量必须实际上是最终变量。

    一个例子:

        public static void repeat(String text, int count){
            for (int i = 1;i <= count; i++){
                ActionListener ls = event ->{
                    System.out.println(i + " " + text);
                };
                new Timer(10000,ls).start();
            }
        }

    如上,对于text的打印是合法的,对i的打印却是非法的。text总是指向同一个对象;而i的值却会改变。

    规则:lambda表达式的体与嵌套块有相同的作用域。

    一个例子:

        Path first = Paths.get("usr/bin");
        Comparator<String> comb = (first,second) -> first.length()-second.length();

    以上是非法的。方法中不能有两个同名的局部变量。所以以上lambda表达式不能使用first变量名作为参数。

    处理lambda表达式

    简单例子:重复一个动作n次,用到repeat方法。

    repeat(10,()->(System.out.println("hello world"));

    需要实现一个函数式接口,这里使用Runnable接口,调用action.run()时会执行这个函数主体:

    public static void repeat(int n,Runnable action){
        for(int i;i<n;i++) action.run();
    }

    实际上lambda表达式能做的也就是转换成函数式接口。

    一些常用的函数式接口:Runnable,Supplier,Consumer,BiConsumer,Function,BiFunction,UnaryOperator,BinaryOperator,Predicate,BiPredicate。

  • 相关阅读:
    理解session
    java ee后台运行原理(Servlet)
    XML:是什么?怎样工作的?可以做什么?将来的发展有会怎样?
    互联网应用与企业级应用的区别
    自我介绍
    补充第一周
    第一周代码(四则运算)
    自我介绍
    程序1:自动生成小学四则运算题目
    初读《构建之法现代软件工程》的5个疑问
  • 原文地址:https://www.cnblogs.com/lht-record/p/8380041.html
Copyright © 2011-2022 走看看