400-870-1191

当前位置:首页 > 技术交流 > Lambda入门使用介绍

Lambda入门使用介绍

2018/07/17 17:26 分类: 技术交流 浏览:3

Java SE 8中新引入的lambda,今天我们介绍一下lambda的使用入门。lambda表达式允许你通过表达式来代替功能接口。 lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)。基本语法是: (参数列表) ->{执行体}

 

1. 函数式接口

说到lambda不得不说和函数式接口的使用。对于函数式接口,简单理解就是一个接口中只有一个抽象的接口方法。当然我们为了更加准确的表示函数式接口可以在接口上加一个注解:@FunctionalInterface(当然,也可以不加此注解),这样当其中有超过一个抽象方法时就会报错。

比如定义一个函数式接口:只有一个抽象方法getUser,下面两种定义都是可以的:

方式一:

@FunctionalInterface//显示加上@FunctionalInterface注解

public interface IUserService {

 

/**

 *获取一个User对象

 * @param id

 * @param name

 * @return

 */

User getUser(Long id,String name);

}

方式二:

//不加注解

public interface IUserService {

 

/**

 *获取一个User对象

 * @param id

 * @param name

 * @return

 */

User getUser(Long id,String name);

}

 

 

 

2. Lambda替代匿名内部类

Lambda很大一个用处就是替代匿名内部类。比如定义一个方法,传入IUserService参数进行业务操作:

场景一:

辅助代码

/**

 * 定义一个方法,需要传入IUserService做为参数

 *

 * @param service

 */

private void userService(IUserService service) {

Long id = 1L;

String name = "lambdaName";

// 调用IUserService接口的getUser方法

User user = service.getUser(id, name);

System.out.println(user);

}

使用匿名内部类调用:

@Test

public void method1Test() {

//调用userService需要传入一个IUserService接口:

//但是我们的接口现在没有实现,所以传入一个匿名内部类做为参数,并覆写getUser方法

userService(new IUserService() {

@Override

public User getUser(Long id, String name) {

System.out.println("id="+id);

System.out.println("name="+name);

return new User(id, name);

}

});

}

 

执行结果:

id=1

name=lambdaName

User [id=1, name=lambdaName]

 

使用lambda实现:

@Test

public void lambdaTest() {

//调用userService需要传入一个IUserService接口. lambda的语法:(参数列表)->{方法体}

//现在我们调用userService方法需要传入一个IUserService接口,这个接口是函数式接口,

//这个一个User getUser(Long id,String name);方法,所以参数列表就是:(Long id,String name)

//函数体:你自己的业务逻辑:

userService((Long id, String name) -> {

System.out.println("id=" + id);

System.out.println("name=" + name);

return new User(id, name);

});

执行结果:

id=1

name=lambdaName

User [id=1, name=lambdaName

从上面实例中发现使用lambda可以替代匿名内部类,简化我们的代码。

我们根据lambda语法自己定义个函数接口定义来体验了一下,接下来看看jdk中一些api的使用,进一步体验lambda的好处,比如显示线程的使用方式:

场景二:

使用匿名内部类:

 

@Test

public void threadTest() throws Exception {

//线程Thread的使用,创建一个对象实例,需要传一个Runnable接口,我们传统方式使用匿名内部类

Thread thread=new Thread(new Runnable() {

@Override

public void run() {

System.out.println("我是一个thread的匿名内部类使用方式!");

}

});

thread.start();

}

使用lambda实现:

 

@Test

public void threadLambdaTest() throws Exception {

//使用lambda方式:因为需要Runnable接口,这个接口是函数式接口,只有一个run方法,这个方法没有

//参数:所以参数列表是()

//{}里写方法体

Thread thread=new Thread(()->{System.out.println("我是一个thread的匿名内部类使用方式!");});

thread.start();

}

源码分析:

Tread的源码分析:

发现这个构造函数需要传入一个Runnable接口,再跟踪源码发现这个接口正好就是一个函数是接口:

所以符合我们lambda的使用场景。

 

3. 小结:

从上面两个实例中,发现使用lambda语法,可以替代匿名内部类作为参数的情况,精简我们代码,具体语法:(参数列表)->{执行体}。当然在jdk中还有很多情况可以使用lambda的情况,比如使用lambda表达式对集合进行迭代,用lambda表达式实现map等等,感兴趣的同学可以网络查看更多的学习资料。

#标签:Lambda,源码时代,Java8