Lambda Expressions Advance
- Person Detail
package com.sean.base; import java.time.LocalDate; public class Person
{ public enum Sex { MALE, FEMALE }String name; LocalDate birthday; Sex gender; String emailAddress;
public Person(String name, Sex gender, LocalDate birthday) { this.name
= name; this.gender = gender; this.birthday = birthday; }public int getAge() { return LocalDate.now().getYear() -
birthday.getYear(); }public Sex getGender() { return gender; }
public String getName() { return name; } }
- Approach 1: Create Methods That Search for Members That Match One
public static List<Person> getPersonsOlderThan(List<Person> roster, int age) {
List<Person> persons = new ArrayList<>();
for (Person p : roster) {
if (p.getAge() >= age) {
persons.add(p);
}
}
return persons;
}
@Test(dataProvider = "persons")
public void testGetPersonsOlderThan(Person[] persons) {
List<Person> oldPersons = PersonUtil.getPersonsOlderThan(Arrays.asList(persons), 30);
Assert.assertEquals(2, oldPersons.size());
Assert.assertTrue(oldPersons.contains(sean));
Assert.assertTrue(oldPersons.contains(wanyu));
}
- Approach 2: Create More Generalized Search Methods
public static List<Person> getPersonsWithinAgeRange(List<Person> roster, int low, int high) {
List<Person> persons = new ArrayList<>();
for (Person p : roster) {
if (low <= p.getAge() && p.getAge() < high) {
persons.add(p);
}
}
return persons;
}
@Test(dataProvider = "persons")
public void testGetPersonsWithinAgeRange(Person[] persons) {
List<Person> oldPersons = PersonUtil.getPersonsWithinAgeRange(Arrays.asList(persons), 30, 40);
Assert.assertEquals(1, oldPersons.size());
Assert.assertTrue(oldPersons.contains(sean));
}
- Approach 3: Specify Search Criteria Code in a Local Class
public static List<Person> getPersons(List<Person> roster, CheckPerson tester) {
List<Person> persons = new ArrayList<>();
for (Person p : roster) {
if (tester.test(p)) {
persons.add(p);
}
}
return persons;
}
@Test(dataProvider = "persons")
public void testGetPersons(Person[] persons) {
List<Person> oldPersons = PersonUtil.getPersons(Arrays.asList(persons),
new CheckPersonEligibleForSelectiveService());
Assert.assertEquals(1, oldPersons.size());
Assert.assertTrue(oldPersons.contains(sean));
}
- Approach 4: Specify Search Criteria Code in an Anonymous Class
@Test(dataProvider = "persons")
public void testAnonymousGetPersons(Person[] persons) {
List<Person> oldPersons = PersonUtil.getPersons(Arrays.asList(persons), new CheckPerson() {
@Override
public boolean test(Person p) {
return p.gender == Person.Sex.MALE && p.getAge() >= 30 && p.getAge() <= 40;
}
});
Assert.assertEquals(1, oldPersons.size());
Assert.assertTrue(oldPersons.contains(sean));
}
- Approach 5: Specify Search Criteria Code with a Lambda Expression
@Test(dataProvider = "persons")
public void testAnonymousLambdaGetPersons(Person[] persons) {
List<Person> oldPersons = PersonUtil.getPersons(Arrays.asList(persons),
(Person p) -> p.getGender() == Person.Sex.MALE && p.getAge() <= 40 && p.getAge() >= 30);
Assert.assertEquals(1, oldPersons.size());
Assert.assertTrue(oldPersons.contains(sean));
}
- Approach 6: Use Standard Functional Interfaces with Lambda Expressions
public static List<Person> getPersonsWithPredicate(List<Person> roster, Predicate<Person> tester) {
List<Person> persons = new ArrayList<>();
for (Person p : roster) {
if (tester.test(p)) {
persons.add(p);
}
}
return persons;
}
@Test(dataProvider = "persons")
public void testGetPersonsWithPredicate(Person[] persons) {
List<Person> oldPersons = PersonUtil.getPersonsWithPredicate(Arrays.asList(persons),
(Person p) -> p.getGender() == Person.Sex.MALE && p.getAge() <= 40 && p.getAge() >= 30);
Assert.assertEquals(1, oldPersons.size());
Assert.assertTrue(oldPersons.contains(sean));
}
- Approach 7: Use Lambda Expressions Throughout Your Application
public static void processPersons(List<Person> roster, Predicate<Person> tester, Consumer<Person> block) {
for (Person p : roster) {
if (tester.test(p)) {
block.accept(p);
}
}
}
public void testProcessPersons(Person[] persons) {
PersonUtil.processPersons(Arrays.asList(persons),
(Person p) -> p.getGender() == Person.Sex.MALE && p.getAge() <= 40 && p.getAge() >= 30,
p -> Assert.assertEquals(sean, p));
}
- Approach 8: Use Generics More Extensively
public static <X, Y> void processPersonsWithGenerics(Iterable<X> source, Predicate<X> tester, Function<X, Y> mapper,
Consumer<Y> block) {
for (X p : source) {
if (tester.test(p)) {
Y data = mapper.apply(p);
block.accept(data);
}
}
}
public void testProcessPersonsWithGenerics(Person[] persons) {
PersonUtil.processPersonsWithGenerics(Arrays.asList(persons),
p -> p.getGender() == Person.Sex.MALE && p.getAge() <= 40 && p.getAge() >= 30, p -> p.getName(),
name -> Assert.assertEquals(sean.getName(), name));
}
- Approach 9: Use Aggregate Operations That Accept Lambda Expressions as Parameters
@Test(dataProvider = "persons")
public void testProcessPersonsWithParameters(Person[] persons) {
Arrays.asList(persons).stream()
.filter(p -> p.getGender() == Person.Sex.MALE && p.getAge() >= 18 && p.getAge() <= 25)
.map(p -> p.getName()).forEach(name -> Assert.assertEquals(sean.getName(), name));
}