假设我们有一个场景:需要查询指定条件的人员信息,Person类定义了人员属性,Utils生成我们需要的人员名单,下面的例子我们来探讨下,
Person:
package crelle.test.java.other.beans;
import java.time.LocalDate;
/**
* @author:crelle
* @className:Person
* @version:1.0.0
* @date:2020/8/15
* @description:XX
**/
public class Person {
public enum Sex {
MALE, FEMALE
}
private String name;
private LocalDate birthday;
private Sex gender;
private String emailAddress;
private int age;
public void printPerson() {
System.out.println(toString());
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public LocalDate getBirthday() {
return birthday;
}
public void setBirthday(LocalDate birthday) {
this.birthday = birthday;
}
public Sex getGender() {
return gender;
}
public void setGender(Sex gender) {
this.gender = gender;
}
public String getEmailAddress() {
return emailAddress;
}
public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", birthday=" + birthday +
", gender=" + gender +
", emailAddress='" + emailAddress + '\'' +
", age=" + age +
'}';
}
}
Utils:
package crelle.test.java.other;
import crelle.test.java.other.beans.Order;
import crelle.test.java.other.beans.Person;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
/**
* @author:crelle
* @className:utils
* @version:1.0.0
* @date:2020/8/15
* @description:XX
**/
public class Utils {
public static List<Person> getPersonsLists(){
List<Person> personList = new ArrayList<Person>();
Person person1 = new Person();
person1.setAge(15);
LocalDate localDate1 = LocalDate.of(2020,4,1);
person1.setBirthday(localDate1);
person1.setGender(Person.Sex.MALE);
person1.setEmailAddress("123@qq.com");
person1.setName("tom");
personList.add(person1);
Person person2 = new Person();
person2.setAge(17);
LocalDate localDate2 = LocalDate.of(2020,6,1);
person2.setBirthday(localDate2);
person2.setGender(Person.Sex.MALE);
person2.setEmailAddress("456@qq.com");
person2.setName("john");
personList.add(person2);
Person person3 = new Person();
person3.setAge(19);
LocalDate localDate3 = LocalDate.of(2020,8,1);
person3.setBirthday(localDate3);
person3.setGender(Person.Sex.FEMALE);
person3.setEmailAddress("789@qq.com");
person3.setName("lili");
personList.add(person3);
return personList;
}
}
1、获取年龄为15的人员
方法的入参为人员集合,年龄
package crelle.test.java.util.function.lambdatutorials;
import crelle.test.java.other.Utils;
import crelle.test.java.other.beans.Person;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
/**
* @author:crelle
* @className:Approach1
* @version:1.0.0
* @date:2020/8/15
* @description: Create Methods That Search for Members That Match One Characteristic
**/
public class Approach1 {
public static void main(String[] args) {
printPersonsOlderThan(Utils.getPersonsLists(),15);
}
public static void printPersonsOlderThan(List<Person> roster, int age) {
for (Person p : roster) {
if (p.getAge() >= age) {
p.printPerson();
}
}
}
}
现在我们想获取年龄在16-25之间的人员
2、获取年龄在16-25之间的人员
方法的入参为人员集合,年龄范围
package crelle.test.java.util.function.lambdatutorials;
import crelle.test.java.other.Utils;
import crelle.test.java.other.beans.Person;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
/**
* @author:crelle
* @className:Approach1
* @version:1.0.0
* @date:2020/8/15
* @description: Create More Generalized Search Methods
**/
public class Approach2 {
public static void main(String[] args) {
printPersonsWithinAgeRange(Utils.getPersonsLists(),16,25);
}
public static void printPersonsWithinAgeRange(
List<Person> roster, int low, int high) {
for (Person p : roster) {
if (low <= p.getAge() && p.getAge() < high) {
p.printPerson();
}
}
}
}
我们做一个改进,把查询条件做一个抽取,我们抽取一个接口CheckPerson:
package crelle.test.java.util.function.lambdatutorials;
import crelle.test.java.other.beans.Person;
/**
* @author:crelle
* @className:CheckPerson
* @version:1.0.0
* @date:2020/8/15
* @description:XX
**/
public interface CheckPerson {
boolean test(Person p);
}
3、查询16-25的男性
方法的入参为人员集合,CheckPerson实现类
package crelle.test.java.util.function.lambdatutorials;
import crelle.test.java.other.Utils;
import crelle.test.java.other.beans.Person;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
/**
* @author:crelle
* @className:Approach1
* @version:1.0.0
* @date:2020/8/15
* @description: Specify Search Criteria Code in a Local Class
**/
public class Approach3 {
public static void main(String[] args) {
printPersons(Utils.getPersonsLists(), new CheckPersonEligibleForSelectiveService());
}
public static void printPersons(
List<Person> roster, CheckPerson tester) {
for (Person p : roster) {
if (tester.test(p)) {
p.printPerson();
}
}
}
}
class CheckPersonEligibleForSelectiveService implements CheckPerson {
public boolean test(Person p) {
return p.getGender() == Person.Sex.MALE &&
p.getAge() >= 16 &&
p.getAge() <= 25;
}
}
可以看出我们的条件入参由基本类型演变成了一个接口的实现类,下面我们用匿名类实现
4、查询16-25的男性
package crelle.test.java.util.function.lambdatutorials;
import crelle.test.java.other.Utils;
import crelle.test.java.other.beans.Person;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
/**
* @author:crelle
* @className:Approach1
* @version:1.0.0
* @date:2020/8/15
* @description: Specify Search Criteria Code in an Anonymous Class
**/
public class Approach4 {
public static void main(String[] args) {
printPersons(Utils.getPersonsLists(),new CheckPerson() {
public boolean test(Person p) {
return p.getGender() == Person.Sex.MALE &&
p.getAge() >= 16 &&
p.getAge() <= 25;
}
}
);
}
public static void printPersons(
List<Person> roster, CheckPerson tester) {
for (Person p : roster) {
if (tester.test(p)) {
p.printPerson();
}
}
}
}
条件入参我们还可以做改变,我们替换匿名类用lambda表达式来实现
5、查询16-25的男性
package crelle.test.java.util.function.lambdatutorials;
import crelle.test.java.other.Utils;
import crelle.test.java.other.beans.Person;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
/**
* @author:crelle
* @className:Approach1
* @version:1.0.0
* @date:2020/8/15
* @description: Specify Search Criteria Code with a Lambda Expression
**/
public class Approach5 {
public static void main(String[] args) {
printPersons(Utils.getPersonsLists(),(Person p) -> p.getGender() == Person.Sex.MALE && p.getAge() >= 16 && p.getAge() <= 25);
}
public static void printPersons(
List<Person> roster, CheckPerson tester) {
for (Person p : roster) {
if (tester.test(p)) {
p.printPerson();
}
}
}
}
我们仔细研究一下CheckPerson接口,返现只有一个抽象方法,输入为对象,输出为boolean类型,我们发现和下面的接口test方法很像:

我替换CheckPerson来使用它
6、查询16-25的男性
package crelle.test.java.util.function.lambdatutorials;
import crelle.test.java.other.Utils;
import crelle.test.java.other.beans.Person;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
/**
* @author:crelle
* @className:Approach1
* @version:1.0.0
* @date:2020/8/15
* @description: Use Standard Functional Interfaces with Lambda Expressions
**/
public class Approach6 {
public static void main(String[] args) {
printPersonsWithPredicate(Utils.getPersonsLists(),(Person p) -> p.getGender() == Person.Sex.MALE && p.getAge() >= 16 && p.getAge() <= 25);
}
public static void printPersonsWithPredicate(
List<Person> roster, Predicate<Person> tester) {
for (Person p : roster) {
if (tester.test(p)) {
p.printPerson();
}
}
}
}
我们可以把打印人员明细单独抽取出来,作为一个入参
7、查询16-25的男性
package crelle.test.java.util.function.lambdatutorials;
import crelle.test.java.other.Utils;
import crelle.test.java.other.beans.Person;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
/**
* @author:crelle
* @className:Approach1
* @version:1.0.0
* @date:2020/8/15
* @description: Use Lambda Expressions Throughout Your Application
**/
public class Approach7 {
public static void main(String[] args) {
processPersons(Utils.getPersonsLists(), p -> p.getGender() == Person.Sex.MALE && p.getAge() >= 16 && p.getAge() <= 25, p -> p.printPerson()
);
}
public static void processPersons(
List<Person> roster,
Predicate<Person> tester,
Consumer<Person> block) {
for (Person p : roster) {
if (tester.test(p)) {
block.accept(p);
}
}
}
}
8、查询16-25的男性,并且打印他们的电子邮箱
package crelle.test.java.util.function.lambdatutorials;
import crelle.test.java.other.Utils;
import crelle.test.java.other.beans.Person;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
/**
* @author:crelle
* @className:Approach1
* @version:1.0.0
* @date:2020/8/15
* @description: Specify Search Criteria Code with a Lambda Expression
**/
public class Approach8 {
public static void main(String[] args) {
processPersonsWithFunction(
Utils.getPersonsLists(),
p -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 16
&& p.getAge() <= 25,
p -> p.getEmailAddress(),
email -> System.out.println(email)
);
}
public static void processPersonsWithFunction(
List<Person> roster,
Predicate<Person> tester,
Function<Person, String> mapper,
Consumer<String> block) {
for (Person p : roster) {
if (tester.test(p)) {
String data = mapper.apply(p);
block.accept(data);
}
}
}
}
我们用到了下面的函数式接口

T – the type of the input to the function 函数输入
R – the type of the result of the function 函数输出
我们使用强大的stream配合lambda来实现查询16-25的男性,并且打印他们的电子邮箱
9、查询16-25的男性,并且打印他们的电子邮箱
package crelle.test.java.util.function.lambdatutorials;
import crelle.test.java.other.Utils;
import crelle.test.java.other.beans.Person;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
/**
* @author:crelle
* @className:Approach1
* @version:1.0.0
* @date:2020/8/15
* @description: Use Aggregate Operations That Accept Lambda Expressions as Parameters
**/
public class Approach9 {
public static void main(String[] args) {
Utils.getPersonsLists()
.stream()
.filter(
p -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 12
&& p.getAge() <= 25)
.map(p -> p.getEmailAddress())
.forEach(email -> System.out.println(email));
}
}
实现同一个功能代码少了多少,自己体会。
完毕!