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。

  • 相关阅读:
    hdu 1269 迷宫城堡 (并查集)
    hdu 1272 小希的迷宫 (深搜)
    hdu 1026 Ignatius and the Princess I (深搜)
    hdu 1099 Lottery
    hdu 1068 Girls and Boys (二分匹配)
    几个基础数位DP(hdu 2089,hdu 3555,uestc 1307 windy 数)
    hdu 1072 Nightmare (广搜)
    hdu 1398 Square Coins (母函数)
    hdu 1253 胜利大逃亡 (深搜)
    hdu 1115 Lifting the Stone (求重心)
  • 原文地址:https://www.cnblogs.com/lht-record/p/8380041.html
Copyright © 2011-2022 走看看