天天看点

java8之Lambda表达式Lamdba的出生Lambda脸谱

希望大家踊跃评论,相互交流,共同进步。

Lamdba的出生

Lamdba的出现是解决什么痛点呢?出现之后有没有带来新的问题呢?该不该使用它?什么情况下适合使用它?

痛点

原来

List<String> names = Arrays.asList("peter", "anna", "mike", "xen
ia");
Collections.sort(names, new Comparator<String>() {
@Override
public int compare(String a, String b) {
return b.compareTo(a);
}
});
           

现在

看上去是简单多了,但是对我们的编程效率有提升嘛?这样简对编译效率有没有影响?对我们维护有没有影响?

对编程效率好像没怎么提升,虽然之前看上去比较复杂,但是都是自动生成的,方法体和返回肯定要自己手写;

对编译效率我自己还没搞清楚,有人说lambda会生成静态方法比起以前匿名内部类会生成类文件效率高点(知道他为啥这样说的可以在下面评论告诉我);

对维护嘛,我经过调试lambda表达式不利于调试可能对以后的查错修改会带来不便。

所以什么地方合适用它,笔者认为那就是实现部分只是单个语句不然后面不便于维护。

Lambda脸谱

基本语法

(parameters) -> expression
或
(parameters) ->{ statements; }
           

可选参数类型声明:无需写参数的类型,编译器会找到函数接口去匹配,就像方法的引用一样。

参数的圆括号:一个参数可不写,多个参数必须写。

方法体大括号:如果只有一个方法体只有一句可以直接用表达式表示如果需要返回也不用写return表达式结果,也不用写分号;如果写了大括号就代表普通的方法体。

注意Lambda只适用于函数接口,即一个接口只有一个抽象函数,当然可以有default函数。加上@FunctionalInterface 标注,编译器会注意到这个标注,如果你的接口中定义了第二个抽象方法的话,编译器会抛出异常

访问变量

@FunctionalInterface
interface InterfaceTest{
      void eat(String a);
//      void ea();
//    public abstract void st(String a,String b);
}
           

局部变量

匿名内部类和Lamdba表达式访问的局部变量是不可以改变的。你可以试下下面的代码:

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Test {
    public static void main(String[] args) {
        List<String> names= Arrays.asList("qww","qw","qwg","qwh");
        String o="dgv";
        Collections.sort(names, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                o1=o1+o2;
                o2=o;
                o="";
                return o1.compareTo(o2);
            }
        });
        o="";
        Collections.sort(names,(s1,s2)-> {s1=s1+s2;s2=s1;return s1.compareTo(s2);});
        String s="dd";
        stringPlus(names,s1-> s1=s);
        s="BG";
    }
    public static String stringPlus(List<String> names,InterfaceTest interfaceTest){
        String s=null;
        for (String name:names
             ) {
            interfaceTest.eat(name);
        }
        return s;
    }
}
           

会发现你想要改变变量o和s的值是不可能的,可以理解为你其他类没有权限改变别的类传来的值,而你要传值给别人不能在传给别人的时候改变值。很多人说是值默认为final感觉理解不对,它只是面对这些约束,要想显示的表明只能用final修饰。

类成员变量

类成员变量没有约束,在类中任意位置可以被访问。

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Test {
    static String str="oppp";
    public static void main(String[] args) {
        List<String> names= Arrays.asList("qww","qw","qwg","qwh");
        String o="dgv";
        Collections.sort(names, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                o1=o1+o2;
                str="iou";
                o2=str;
                return o1.compareTo(o2);
            }
        });
        str="";
        Collections.sort(names,(s1,s2)-> {s1=s1+s2;s2=s1;return s1.compareTo(s2);});
        String s="dd";
        stringPlus(names,s1-> s1=s);
    }
    public static String stringPlus(List<String> names,InterfaceTest interfaceTest){
        String s=null;
        for (String name:names
             ) {
            interfaceTest.eat(name);
        }
        return s;
    }
}