在 Java 8 之前,匿名内部类,监听器和事件处理器的使用都显得很冗长,代码可读性很差。
在Java 8 之前使用匿名内部类:
- 例如
interface ITestPrint{ public void print(); } public class TestLambda { public static void fun(ITestPrint testPrint){ testPrint.print(); } public static void main(String[] args) { fun(new ITestPrint() { @Override public void print() { System.out.println("普通的匿名内部类方法调用!"); } }); } }
可以看出我们只需打印一句话就多了特别多的冗余代码,所以在Java 8 引入了 函数式编程
Lambda 表达式的应用则使代码变得更加紧凑,可读性增强。
Lambda 表达式使并行操作大集合变得很方便,可以充分发挥多核 CPU 的优势,更易于为多核处理器编写代码。
- 范例使用 Lambda 表达式
-
//修改为Lambda表达式 fun(()-> System.out.println("使用 Lambda 表达式,一句话搞定!"));
Lambda 表达式由三个部分组成:
-
第一部分为一个括号内用逗号分隔的形式参数,参数是函数式接口里面方法的参数;
-
第二部分为一个箭头符号:->;
-
第三部分为方法体,可以是表达式和代码块。
-
Lambda 语法的三种形式:
-
- (参数)->单行语句;
- (参数)->{单行或多行语句};
- (参数)->表达式;
- 例如:
interface ITestPrint{ public void printStr(String str); } interface ITestAdd{ public int add(int numa,int numb); } public class TestLambda { public static void funPrint(ITestPrint testPrint){ testPrint.printStr("带参数语句"); } public static void funAdd(ITestAdd testAdd){ System.out.println(testAdd.add(10,20)); } public static void main(String[] args) { //参数 -> 单行语句 funPrint((str)-> System.out.println(str)); //参数 -> 多行语句 funPrint((str) -> { str.toUpperCase(); System.out.println(str); }); //表达式形式 funAdd(((numA, numB) -> numA + numB)); } }
要使用 Lambda 表达式,需要定义一个函数式接口,这样往往会让程序充斥着过量的仅为 Lambda 表达式服务的函数式接口。
为了减少这样过量的函数式接口,Java 8 在 java.util.function 中增加了不少新的函数式通用接口。
例如:
- Function<T, R>:将 T 作为输入,返回 R 作为输出,他还包含了和其他函数组合的默认方法。
- Predicate<T> :将 T 作为输入,返回一个布尔值作为输出,该接口包含多种默认方法来将 Predicate 组合成其他复杂的逻辑(与、或、非)。
- Consumer<T> :将 T 作为输入,不返回任何内容,表示在单个参数上的操作。
interface PersonInterface { public boolean test(Person person); } public class People { private List<Person> persons= new ArrayList<Person>(); public List<Person> getMaleList(PersonInterface filter) { List<Person> res = new ArrayList<Person>(); persons.forEach( (Person person) -> { if (filter.test(person)) {//调用 PersonInterface 的方法 res.add(person); } } ); return res; } } //为了去除 PersonInterface 这个函数式接口,可以用通用函数式接口 Predicate 替代如下: class People{ private List<Person> persons= new ArrayList<Person>(); public List<Person> getMaleList(Predicate<Person> predicate) { List<Person> res = new ArrayList<Person>(); persons.forEach( person -> { if (predicate.test(person)) {//调用 Predicate 的抽象方法 test res.add(person); } }); return res; } }