java.util.function 包
当然Predicate 不是Java SE8提供的唯一函数式接口。此外还设计了一些标准的接口作为开发者的首要选择.
- Predicate :将Object的属性作为参数传递
- Consumer :将Object执行的动作作为参数传递
- Function :将类型T转换成类型U
- Supplier :提供泛型T的实例(好像一个工厂模式)
- UnaryOperator :从T到T的一元操作
- BinaryOperator :从(T,T)到T的二元操作
此外,这些接口许多都已经有原始版本。这些应该做为你的Lambda表达式良好的起始点。
东方风格的名字和方法引用
当正在编写前面的事例的时候,我决定它将是对Person类来说很灵活的打印系统。一个功能需求就是它既能显示西方风格的名字又能显示东方风格的名字。在西方国家,通常是名字在前,姓氏在后。但在许多东方文化中,一般是姓氏在前,名字在后。
一个旧式风格的例子
下面示例是在没有Lambda支持下如何实现Person打印类。
Person.java
public void printWesternName(){
System.out.println("\nName: " + this.getGivenName() + " " + this.getSurName() + "\n" +
"Age: " + this.getAge() + " " + "Gender: " + this.getGender() + "\n" +
"EMail: " + this.getEmail() + "\n" +
"Phone: " + this.getPhone() + "\n" +
"Address: " + this.getAddress());
}
public void printEasternName(){
System.out.println("\nName: " + this.getSurName() + " " + this.getGivenName() + "\n" +
"Age: " + this.getAge() + " " + "Gender: " + this.getGender() + "\n" +
"EMail: " + this.getEmail() + "\n" +
"Phone: " + this.getPhone() + "\n" +
"Address: " + this.getAddress());
}
每一种风格都对应一个方法来打印输出一个Person
The Function Interface
Function接口对于这种问题很有用。它只有一个方法apply具备下面的特征:
public R apply(T t){ }
它传递有一个泛型T参数,返回一个泛型R。对于这个示例来说,传递Person类和返回String
。对Person一个更灵活的打印方法应该像下面这样写:
Person.java
public String printCustom(Function <Person, String> f){
return f.apply(this);
}
这个示例相对简单一些。一个Function接口被传递到方法中返回一个String。这个apply方法处理Lambda表达式将决定什么样的Person信息将被返回。
这些Function是如何定义的呢?下面是测试代码将调用前面的方法。
NameTestNew.java
public class NameTestNew {
public static void main(String[] args) {
System.out.println("\n==== NameTestNew02 ===");
List<Person> list1 = Person.createShortList();
// Print Custom First Name and e-mail
System.out.println("===Custom List===");
for (Person person:list1){
System.out.println(
person.printCustom(p -> "Name: " + p.getGivenName() + " EMail: " + p.getEmail())
);
}
// Define Western and Eastern Lambdas
Function<Person, String> westernStyle = p -> {
return "\nName: " + p.getGivenName() + " " + p.getSurName() + "\n" +
"Age: " + p.getAge() + " " + "Gender: " + p.getGender() + "\n" +
"EMail: " + p.getEmail() + "\n" +
"Phone: " + p.getPhone() + "\n" +
"Address: " + p.getAddress();
};
Function<Person, String> easternStyle = p -> "\nName: " + p.getSurName() + " "
+ p.getGivenName() + "\n" + "Age: " + p.getAge() + " " +
"Gender: " + p.getGender() + "\n" +
"EMail: " + p.getEmail() + "\n" +
"Phone: " + p.getPhone() + "\n" +
"Address: " + p.getAddress();
// Print Western List
System.out.println("\n===Western List===");
for (Person person:list1){
System.out.println(
person.printCustom(westernStyle)
);
}
// Print Eastern List
System.out.println("\n===Eastern List===");
for (Person person:list1){
System.out.println(
person.printCustom(easternStyle)
);
}
}
}
第一个循环只是打印名字和email地址。但是任何合法的表达式都可以传递给printCustom方法。东方和西方的打印风格都是使用Lambda表达式定义并存储在一个变量中。这些变量传递给后两个循环中。这些Lambda表达式可以合并到Map中这样能够更容易的复用它们。Lambda表达式提供了很好的灵活性。
示例输出
下面是程序的示例输出结果
==== NameTestNew02 ===
===Custom List===
Name: Bob EMail: bob.baker@example.com
Name: Jane EMail: jane.doe@example.com
Name: John EMail: john.doe@example.com
Name: James EMail: james.johnson@example.com
Name: Joe EMail: joebob.bailey@example.com
Name: Phil EMail: phil.smith@examp;e.com
Name: Betty EMail: betty.jones@example.com
===Western List===
Name: Bob Baker
Age: 21 Gender: MALE
EMail: bob.baker@example.com
Phone: 201-121-4678
Address: 44 4th St, Smallville, KS 12333
Name: Jane Doe
Age: 25 Gender: FEMALE
EMail: jane.doe@example.com
Phone: 202-123-4678
Address: 33 3rd St, Smallville, KS 12333
Name: John Doe
Age: 25 Gender: MALE
EMail: john.doe@example.com
Phone: 202-123-4678
Address: 33 3rd St, Smallville, KS 12333
Name: James Johnson
Age: 45 Gender: MALE
EMail: james.johnson@example.com
Phone: 333-456-1233
Address: 201 2nd St, New York, NY 12111
Name: Joe Bailey
Age: 67 Gender: MALE
EMail: joebob.bailey@example.com
Phone: 112-111-1111
Address: 111 1st St, Town, CA 11111
Name: Phil Smith
Age: 55 Gender: MALE
EMail: phil.smith@examp;e.com
Phone: 222-33-1234
Address: 22 2nd St, New Park, CO 222333
Name: Betty Jones
Age: 85 Gender: FEMALE
EMail: betty.jones@example.com
Phone: 211-33-1234
Address: 22 4th St, New Park, CO 222333
===Eastern List===
Name: Baker Bob
Age: 21 Gender: MALE
EMail: bob.baker@example.com
Phone: 201-121-4678
Address: 44 4th St, Smallville, KS 12333
Name: Doe Jane
Age: 25 Gender: FEMALE
EMail: jane.doe@example.com
Phone: 202-123-4678
Address: 33 3rd St, Smallville, KS 12333
Name: Doe John
Age: 25 Gender: MALE
EMail: john.doe@example.com
Phone: 202-123-4678
Address: 33 3rd St, Smallville, KS 12333
Name: Johnson James
Age: 45 Gender: MALE
EMail: james.johnson@example.com
Phone: 333-456-1233
Address: 201 2nd St, New York, NY 12111
Name: Bailey Joe
Age: 67 Gender: MALE
EMail: joebob.bailey@example.com
Phone: 112-111-1111
Address: 111 1st St, Town, CA 11111
Name: Smith Phil
Age: 55 Gender: MALE
EMail: phil.smith@examp;e.com
Phone: 222-33-1234
Address: 22 2nd St, New Park, CO 222333
Name: Jones Betty
Age: 85 Gender: FEMALE
EMail: betty.jones@example.com
Phone: 211-33-1234
Address: 22 4th St, New Park, CO 222333
资源链接
点击打开链接