目录
第一篇:JDK8新特性一:引入介绍
第二篇:JDK8新特性二:Lambda表达式引入介绍
第三篇:JDK8新特性二:Lambda表达式规范和语法
第四篇:JDK8新特性二:方法引入详述
第五篇:JDK8新特性二:foreach、排序、线程调用简单示例
第六篇:JDK8新特性三:Stream流+常见方法演示
第七篇:JDK8新特性四:Optional类的学习
JDK8新特性
二 Lambda表达式(*)
1 什么是Lambda表达式
- Lambda表达式是一个匿名函数,简化了调用函数的过程,使用Lambda表达式不仅让代码变的简单、而且可读、最重要的是代码量也随之减少很多。
2 为什么要使用Lambda表达式
2.1 简化使用匿名内部类的使用
-
正常情况下,我们在使用接口的时候,一般都会通过为接口编写实现类,在实现类中重写接口方法,然后构建实现类对象,进而实现调用对应方法的能力。
-
下面演示一下这种普通方式实现
-
接口
// 编写接口 public interface TestService { void add(); }
-
实现类
// 编写实现类 public class TestServiceImpl implements TestService{ @Override public void add() { System.out.println("add()"); } }
-
测试
@Test public void test() { TestServiceImpl testService = new TestServiceImpl(); testService.add(); }
-
-
上面这种方式是最普通的一种实现方式了,也是比较常见的。那么,如果打算使用接口中的方法,但是不想创建实现类,可以实现吗?答案是当然可以
-
我们可以采用匿名内部类的方式去实现它
-
接口
public interface TestService { void add(); }
-
构建匿名内部类并测试
@Test public void test1() { // 方式一:步步为营 TestService testService = new TestService() { @Override public void add() { System.out.println("add()"); } }; testService.add(); // 方式二:一步到位 new TestService() { @Override public void add() { System.out.println("add()"); } }.add(); }
-
上面看到的就是匿名内部类方式使用接口的情况,方式一和方式二本质是一样的,通过使用匿名内部类,为接口待实现的方法进行了实现,然后调用。
-
如大家视觉效果所看的的,这样的方式写代码,代码量也是挺多的,那还能不能进一步简化呢?答案是可以的!这里就要使用到我们jdk8提供的强大的Lambda语法了
- tip:其实强大的IDEA已经为我们做了很多提示了,当鼠标移动到new TestService()上的时候,IDEA已经给出了建议
- 翻译过来就是,这种匿名内部类方式可以被Lambda表达式所替代
-
-
Lambda表达式实现
-
接口
public class TestServiceImpl implements TestService{ @Override public void add() { System.out.println("add()"); } }
-
使用Lambda表达式并测试
@Test public void test2() { // 方式一:步步为营 TestService testService = () -> System.out.println("add()"); testService.add(); // 方式二:一步到位 ((OrderService) () -> System.out.println("add()")).add(); }
-
如果语言等级不匹配时,IDEA会提示,如下,选择第三个即可
-
上面代码就是使用Lambda表达式实现的方式了,从最初实现类方式,到匿名内部类,再到Lambda表达式,是不是感觉代码一步步被优化到了极致呢?确实使用Lambda表达式带给了我们很好的开发效率,但是并不是否认其他方式,不同的方式自有其存在的价值。
-
看到这里,有些小伙伴可能有疑问了,我就写了一个() -> xxxx,然后就调用add()方法就能输出重写接口方法后方法体的内容了,它是怎么做到的呢?或者说这样子使用有什么限制吗?是的,确实有限制,下面演示一下,无法使用Lambda表达式的情况。
-
-
接口中存在多个方法时,Lambda表达式不能使用
-
接口
public interface TwoService { void add(); void get(); }
-
使用匿名内部类并测试
public class TwoServiceTest { @Test public void test() { new TwoService() { @Override public void add() { System.out.println("add()"); } @Override public void get() { System.out.println("get()"); } }.add(); } }
-
在上面这种情况,IDEA也不再给出提示了,这是因为接口中不只一个抽象方法的时候,Lambda表达式就无法使用了,因为Lambda表达式是隐藏了方法的名称,所以只能对于接口中只有一个抽象方法的情况生效。
-
-
接口中含有形参的方法使用Lambda表达式实现
-
接口
public interface TestService { void add(int x, int y); }
-
测试
public class TestServiceImplTest { @Test public void test() { ((TestService) (x, y) -> { System.out.println("x:"+x+",y:"+y); }).add(1,2); } }
-