Java8 lambda表达式

阅读数:14 评论数:0

跳转到新版页面

分类

python/Java

正文

一、概述

1、lambda允许把函数作为一个方法的参数。

二、取代某些匿名内部类

1、无参数函数的简写

如果需要创建一个线程,一种常见的写法是这样:

// JDK7 匿名内部类写法
new Thread(new Runnable(){// 接口名
    @Override
    public void run(){// 方法名
        System.out.println("Thread run()");
    }
}).start();

这是JDK7以及之前的常见写法,匿名内部类省去了起名字的烦恼,但还不够简化,在Java8中可以简化如下形式:

// JDK8 Lambda表达式写法
new Thread(
        () -> System.out.println("Thread run()")// 省略接口名和方法名
).start();

这里连接口名和函数名都一同省掉了,如果函数体有多行,可以用大括号

// JDK8 Lambda表达式代码块写法
new Thread(
        () -> {
            System.out.print("Hello");
            System.out.println(" Hoolee");
        }
).start();

2、带参数函数的简写

// JDK8 Lambda表达式写法
List<String> list = Arrays.asList("I", "love", "you", "too");
Collections.sort(list, (s1, s2) ->{// 省略参数表的类型
    if(s1 == null)
        return -1;
    if(s2 == null)
        return 1;
    return s1.length()-s2.length();
});

代码中参数表的类型也省略了,这得益于javac的类型推断机制,当然也可以手动指明参数类型。

 

三、自定义函数接口

自定义函数接口很容易,只需要编写一个只有一个抽象方法的接口即可。

// 自定义函数接口
@FunctionalInterface
public interface ConsumerInterface<T>{
    void accept(T t);
}

@FunctionalInterface是可选的,但加上该标注编译器会帮你检查接口是否符合函数接口规范。

有了上述接口定义,就可以出类似如下的代码:

ConsumerInterface<String> consumer = str -> System.out.println(str);
 
consumer.accept("你好");

进一步的,还可以这样使用:

class MyStream<T>{
    private List<T> list;
    ...
    public void myForEach(ConsumerInterface<T> consumer){// 1
        for(T t : list){
            consumer.accept(t);
        }
    }
}
MyStream<String> stream = new MyStream<String>();
stream.myForEach(str -> System.out.println(str));// 使用自定义函数接口书写Lambda表达式