可以把Lambda表达式理解为简洁地表示可传递的匿名函数的一种方式:它没有名称,但它有参数列表、函数主体、返回类型。这个定义还是太模糊的,让我们从以下几个关键词慢慢道来。
●匿名——我们说匿名,是因为它不像普通的方法那样有一个明确的名称:写得少而做得多!
●函数——我们说它是函数,是因为Lambda函数不像方法那样属于某个特定的类。但和方法一样,Lambda有参数列表、函数主体、返回类型。
●传递——Lambda表达式可以作为参数传递给方法或存储在变量中。
●简洁——无需像匿名类那样写很多模板代码。
那到这里我们已经清楚了Lambda表达式的基本语法格式,那再继续思考一个问题:是不是所有的接口类型作为参数传递(传统写法就是匿名内部类)都可以使用Lambda表达式呢?
答案是不可以!因为只有接口中只有一个
抽象方法的时候,Lambda表达式才可以正确的“猜测”到你传递的任务实际上是在实现接口中的唯一的那一个抽象方法!
那么我们把这种只有一个抽象方法的接口称作为“函数式接口”,只有函数式接口才可以使用Lambda表达式进行函数式编程!
函数式接口-@FunctionalInterface
只要确保接口中有且仅有一个抽象方法即可
修饰符 interface 接口名称 {
[public abstract] 返回值类型 方法名称(可选参数信息);
// 其他
}
为了便于区分并便于编译器进行语法校验,JDK8中还引入了一个新的注解:
@FunctionalInterface
该注解可用于一个接口的定义上,一旦使用该注解来定义接口,编译器将会强制检查该接口是否确实有且仅有一个抽象方法,否则将会报错。
需要注意的是,即使不使用该注解,只要满足函数式接口的定义,该接口仍然是一个函数式接口,使用起来都一样。(可以类比下@Override 注解的作用)
{
//需求1 启动一个线程 输出Hello world
//传统方式
new Thread( new Runnable() {
@Override
public void run() {
System.out.println( "hello world" );
}
} ).start();
//函数式编程 Lambda
new Thread(()-> System.out.println("hello world Lambda") ).start();
//需求2筛选出大于100 的数据存放在list集合中
//新建list集合
List<Integer> list=new LinkedList<Integer>( );
list.add( 1 );
list.add( 101 );
list.add( 1001 );
list.add( 2 );
//传统方法
//新建list
List<Integer>isOk=new LinkedList <>( );
for (Integer o : list) {
if(o>100){
isOk.add( o );
}
}
//lambdat方法使用strema流的方式
isOk=list.stream().filter( e->e>100).collect( Collectors.toList());
}
//需求三:获取从低到高的排行前3的数据
list.stream().sorted().limit( 3 ).collect( Collectors.toList() )
.forEach( e -> {
System.out.println( e );
} );
网友评论