Lambda入门使用介绍
2018/07/17 17:26 分类: 技术交流 浏览:83
Java SE 8中新引入的lambda,今天我们介绍一下lambda的使用入门。lambda表达式允许你通过表达式来代替功能接口。 lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)。基本语法是: (参数列表) ->{执行体}
1. 函数式接口
说到lambda不得不说和函数式接口的使用。对于函数式接口,简单理解就是一个接口中只有一个抽象的接口方法。当然我们为了更加准确的表示函数式接口可以在接口上加一个注解:@FunctionalInterface(当然,也可以不加此注解),这样当其中有超过一个抽象方法时就会报错。
比如定义一个函数式接口:只有一个抽象方法getUser,下面两种定义都是可以的:
l 方式一:
@FunctionalInterface//显示加上@FunctionalInterface注解
public interface IUserService {
/**
*获取一个User对象
* @param id
* @param name
* @return
*/
User getUser(Long id,String name);
}
l 方式二:
//不加注解
public interface IUserService {
/**
*获取一个User对象
* @param id
* @param name
* @return
*/
User getUser(Long id,String name);
}
2. Lambda替代匿名内部类
Lambda很大一个用处就是替代匿名内部类。比如定义一个方法,传入IUserService参数进行业务操作:
场景一:
l 辅助代码
/**
* 定义一个方法,需要传入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);
}
l 使用匿名内部类调用:
@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]
l 使用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的好处,比如显示线程的使用方式:
场景二:
l 使用匿名内部类:
@Test
public void threadTest() throws Exception {
//线程Thread的使用,创建一个对象实例,需要传一个Runnable接口,我们传统方式使用匿名内部类
Thread thread=new Thread(new Runnable() {
@Override
public void run() {
System.out.println("我是一个thread的匿名内部类使用方式!");
}
});
thread.start();
}
l 使用lambda实现:
@Test
public void threadLambdaTest() throws Exception {
//使用lambda方式:因为需要Runnable接口,这个接口是函数式接口,只有一个run方法,这个方法没有
//参数:所以参数列表是()
//{}里写方法体
Thread thread=new Thread(()->{System.out.println("我是一个thread的匿名内部类使用方式!");});
thread.start();
}
l 源码分析:
Tread的源码分析:
发现这个构造函数需要传入一个Runnable接口,再跟踪源码发现这个接口正好就是一个函数是接口:
所以符合我们lambda的使用场景。
3. 小结:
从上面两个实例中,发现使用lambda语法,可以替代匿名内部类作为参数的情况,精简我们代码,具体语法:(参数列表)->{执行体}。当然在jdk中还有很多情况可以使用lambda的情况,比如使用lambda表达式对集合进行迭代,用lambda表达式实现map等等,感兴趣的同学可以网络查看更多的学习资料。
赞 0