[译]Lambda Expressions in Java 8

原文:http://www.javabeat.net/a-sneak-peak-at-the-lambda-expressions-in-java-8/

Mike Duigou宣布Lambda库的第一部分迭代已经完成,其中包括defender methods(译:Defender Methods)的支持,以及增强了集合类API。 您也可以阅读:

•  Java 8.0 Tutorials

•  Java 7.0 Tutorials

•  New Features in Java 7.0

•  G1 Garbage Collector in Java 7.0

在继续阅读深入之前,最好一定程度上阅读这两篇文章:Functional Interfaces[译文:函数式接口]、Defender Methods[译文:Defender Methods]

让我们看一个例子,思考每个Person objects的排序,每个Person有firstName、 lastName、dateOfBirth、placeOfBirth等属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Person {
public Person(String fName,String lName,Date dob,String place)
{
firstName = fName;
lastName = lName;
dateOfBirth = dob;
placeOfBirth = place;
}
@Override
public String toString(){
return firstName+" "+lastName;
}
String firstName;
String lastName;
Date dateOfBirth;
String placeOfBirth;
}

让我们看看分别在使用和不使用Lambda表达式的情况下怎样排序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class LambdaBasicDemo {
public static void main(String[] args) {
List people = createPeople();
// Sorting pre Lambda Expression era
//Sorting by firstName
Collections.sort(people,new Comparator Person() {
@Override
public int compare(Person o1, Person o2) {
return o1.firstName.compareTo(o2.firstName);
}
});
System.out.println("Firstname sort: "+people);
//Sorting using Lambda expressions and updated collection API
//Sorting by lastName
people.sort((o1,o2) {
return o1.lastName.compareTo(o2.lastName);
});
System.out.println("Lastname sort:" +people);
}
static List Person createPeople(){
Calendar calendar = Calendar.getInstance();
calendar.set(1900, Calendar.JANUARY,01,12,00);
List people = new ArrayList();
Person person = new Person("Raju","Sarkar",calendar.getTime(),"Delhi");
people.add(person);
calendar.set(1950,Calendar.JUNE,30,12,30);
person = new Person("Anant","Patil", calendar.getTime(),"Pune");
people.add(person);
calendar.set(1950,Calendar.DECEMBER,30,12,30);
person = new Person("Danny","Great", calendar.getTime(),"London");
people.add(person);
return people;
}
}

输出:

1
2
Firstname sort: [Anant Patil, Danny Great, Raju Sarkar]
Lastname sort:[Danny Great, Anant Patil, Raju Sarkar]

你应该知道collections是如何使用ollection API和Comparator进行排序的,所以这里不会讲这方面的东西。这里使用了-和>符号,让我们看看这里语法的详细使用:

1
2
3
4
5
//Sorting using Lambda expressions and updated collection API
//Sorting by lastName
people.sort((o1,o2){
return o1.lastName.compareTo(o2.lastName);
});

使用匿名内部类进行排序和使用Lambda表达式进行排序有着明显的不同。Lambda表达式由Lambda参数和Lambda体组成。一个Lambda表达式表示为() -> {},其中()由Lambda参数组成,{}由Lambda实体组成。一个Lambda表达式可以是空返回或者返回一个值。i.e:返回空或返回一个表达式。

在上面的例子中, 我们可以为函数式接口构建Lambda表达式。函数式接口Comparator的表示符为(T o1, T o2) -> int。

注意:在Java8中Comparator有两个方法

1
2
3
4
5
6
Comparator reverse() default {
return Collections.reverseOrder(this);
}
Comparator compose(Comparator super other) default {
return Comparators.compose(this, other);
}

(We would like to keep this confusion aside for time being and I will get back on this and explain as to why and how the defender methods are not considered. If someone if aware of the reason, please add them as comments.)译者注:在Java8中,新增的defender methods如果没有覆写default方法,则默认使用default方法。

挖掘更深的Lambda表达式,(o1, o2)表示Lambda参数,o1和o2的类型由它们正在使用的上下文推导出,此处我们的情况是Person类型,{return o1.lastName.compareTo(o2.lastName);}是Lambda实体。

在匿名内部类方法中使用Lambda表达式的优点:

•  Lambda表达式相对匿名内部类,编码更清晰。

•  使用Lambda表达式的一个优点就是在Lambda表达式内thissuper的有更好的区别。在使用匿名内部类的情况下this和super被解析为匿名内部类,不过也有可能从匿名内部类中什么也不能获取到。但是在Lambda表达式中这些被解析为一个封闭的类。

•  在Lambda表达式中使用非final变量(Java8:effectively final),但是在内部类中只允许访问final修饰的变量。

有趣的是,编译LambdaBasicDemo.java的时候,会产生3个类(除了Person.class): LambdaBasicDemo.class, LambdaBasicDemo$1.class, LambdaBasicDemo$2.class。

•  LambdaBasicDemo.class对应类LambdaBasicDemo

•  LambdaBasicDemo$1.class对应类Comparator的匿名内部类。

•  LambdaBasicDemo$2.class对应lambda表达式。

因此在这种机制下,编译器为Lambda表达式封装了一个新的类并且进行了实例化。

相关文章:

1. Using Lambda Expressions of Java 8 in Java FX event handlers

2. Regular Expressions in Java

3. Virtual Extension Methods(or Defender Methods) in Java 8

4. What are Functional Interfaces and Functional Descriptor?

5. Comparing Objects in Java