java8-lambda表达式

lambda表达式其本质是一个匿名函数,它没有名称,语法规则如下: (参数)->{表达式或函数语句}; 其中,参数可以为空,同时,浅显的参数类型也无需写出来,javac回通过上下文(context)自动推断出参数类型.如果参数只有一个可省去括号. ->用于分离参数和函数体(body). 右侧可以是个表达式,此时不需要花括号;也可以是函数语句,我们可以在lambda表达体中使用break,continue,return. 我们甚至可以从lambda表达体中抛出异常.但lambda不能像一个方法一样使用throws子句. 需要注意的是,lambda表达式隐含了return关键字,所以在单个的表达式中,我们无需显式的写return关键字,但是当表达式是一个语句集合的时候,则需要显式添加return,并用花括号{ }将多个表达式包围起来 示例: x->x+1 (int x, int y) -> x+y (String msg) -> {sout(msg);} ()->{sout("helloworld");} 示例二:
String[] str = {"aa","bb","dd","cc"};
List<String> lists = new ArrayList<>(Arrays.asList(str));
lists.forEach( m -> sout(m) )
示例三:
 Runnable con = new Runnable() {
                @Override
                public void run() {
                    System.out.println("helloworld1");
                }
            };
con.run();
等价于:

Runnable con2 = ()-> System.out.println("hello world2");
con2.run();
示例四:
//返回给定字符串的长度,隐含return语句
(String s) -> s.length() 

// 始终返回42的无参方法
() -> 42 

// 包含多行表达式,则用花括号括起来
(int x, int y) -> {
    int z = x * y;
    return x + z;
}
(**foreach的lambda函数的返回值是void**) 需要注意: 1. lambda可进行类型推断; 2. lambda表达式中不只可用主体函数,也可以使用局部变量,例子如下:
int weight = 100;
List<Apple> filterApples = filterApplesByAppleFilter(apples,
        apple -> Color.RED.equals(apple.getColor()) && apple.getWeight() >= weight);
该例子中我们在lambda中使用了局部变量weight,不过在lambda中使用局部变量必须要求该变量 显式声明为final或事实上的final ,这主要是因为局部变量存储在栈上,lambda表达式则在另一个线程中运行,当该线程视图访问该局部变量的时候,该变量存在被更改或回收的可能性,所以用final修饰之后就不会存在线程安全的问题。 3.  方法引用(::) 采用方法引用可以更近一步的简化代码,有时候这种简化让代码看上去更加的直观,先看一个例子:
/* ... 省略apples的初始化操作 */

// 采用lambda表达式
apples.sort((Apple a, Apple b) -> Float.compare(a.getWeight(), b.getWeight()));

// 采用方法引用
apples.sort(Comparator.comparing(Apple::getWeight));
方法引用通过::将方法隶属和方法自身连接起来,主要分为三类:
静态方法

(args) -> ClassName.staticMethod(args)
转换成
ClassName::staticMethod
参数的实例方法

(args) -> args.instanceMethod()
转换成
ClassName::instanceMethod  // ClassName是args的类型
外部的实例方法

(args) -> ext.instanceMethod(args)
转换成
ext::instanceMethod(args)
 
posted @ 2018-08-10 17:38  zohy  阅读(139)  评论(0编辑  收藏  举报