lambda高效简洁神器
JDK8发布已有不少年头,已然是一个经典的版本。它带来的新特性lambda,你真的有发现和使用它吗?
按照传统的java编程习惯,我们要实现一个排序功能就像下面的例子:
List people = Arrays.asList(person1, person2, person3);
Collections.sort(people, new Comparator() {
@Override
public int compare(Person o1, Person o2) {
return o1.getAge().compareTo(o2.getAge());
}
});
Lambda写法:
Collections.sort(people, (p1, p2) -> p1.getAge().compareTo(p2.getAge()));
Lambda加强版写法:
Collections.sort(people, Comparator.comparing(Person::getAge));
简单的一行代码,不再需要编写一堆的变量引用,望文生义,快速了解代码业务逻辑。
有接触过js的朋友"闭包"大概都了解过,lambda其实也是相同的一个概念。lambda是内部的实现原理是匿名函数的实现,可以理解为简洁的表示可传递的匿名函数的一种方式:它没有名称,但它有参数列表,函数主体,返回类型,可能还有一个可以抛出的异常列表。
java中,引入了一个新的操作符"->",该操作符在很多资料中,称为箭头操作符,或者lambda操作符;箭头操作符将lambda分成了两个部分: 左侧:lambda表达式的参数列表 右侧:lambda表达式中所需要执行的功能,即lambda函数体
lambda由于java是强类型语言,使用Lambda的依据是必须有相应的函数接口 (函数接口,是指内部只有一个抽象方法的接口) JDK8添加了新的注解 @FunctionalInterface 来表明函数接口。函数式接口
函数式接口(Functional Interface)是Java 8对一类特殊类型的接口的称呼。 这类接口只定义了唯一的抽象方法的接口,并且这类接口使用了 @FunctionalInterface 进行注解。函数式接口可以被隐式转换为 lambda 表达式。在jdk8中,引入了一个新的包 java.util.function , 可以使java 8 函数式编程变得更加简便。这个package中的接口大致分为了以下四类: Function: 接收参数,并返回结果,主要方法 R apply(T t) Consumer: 接收参数,无法返回结果, 主要方法为 void accept(T t) Supplier: 不接收参数,但返回结构,主要方法为 T get() Predicate: 接收参数,返回boolean值,主要方法为 boolean test(T t) 方法引用
Lambda 表达式用于表达函数的主体,但如果已经编写/定义了函数/方法,则可以在使用 lambda 表达式的任何地方直接将它们用作方法引用。我们可以看到 lambda 表达式和方法具有相同的用法,只是第一个是匿名的,而后者是命名的。因此,如果我们已经定义了一个方法,则方法引用允许我们按名称使用该方法来代替匿名 lambda 表达式。
有四种方法引用: 1、对静态方法的引用
— ContainingClass::staticMethodName
2、对特定对象的实例方法的引用
— containsObject::instanceMethodName
3、对特定类型的任意对象的实例方法的引用
— ContainingType::methodName
4、对构造函数的引用
— ClassName::newpublic class MethodRef {
public void printLowerCase(String s) {
System.out.println(s.toLowerCase());
}
public static void printUpperCase(String s) {
System.out.println(s.toUpperCase());
}
public void publicMethod() {
List list = Arrays.asList("A", "B", "C");
list.forEach(this::printLowerCase);
list.forEach(MethodRef::printUpperCase);
list.forEach(String::toLowerCase);
list.forEach(String::new);
}
}