原代码:
List<Person> persons = ...; persons.stream().filter(p -> { if (p.getGender() == Gender.MALE) { return true; } LocalDate now = LocalDate.now(); Duration age = Duration.between(p.getBirthDate(), now); Duration adult = Duration.of(18, ChronoUnit.YEARS); return age.compareTo(adult) > 0) { return true; } return false; }).map(p -> p.getFirstName() + " " + p.getLastName()) .collect(Collectors.toList());
|
它很长,甚至令人费解。
第一步是应用正确的命名,并将逻辑移到它所属的位置。
public class Person {
// ...
public boolean isMale() { return getGender() == Gender.MALE; }
public boolean isAdult(LocalDate when) { Duration age = Duration.between(birthDate, when); Duration adult = Duration.of(18, ChronoUnit.YEARS); return age.compareTo(adult) > 0; } }
|
这个小的重构已经提高了lambda的可读性:
persons.stream().filter(p -> { if (p.isMale()) { return true; } LocalDate now = LocalDate.now(); return p.isAdult(now); }).map(p -> p.getFirstName() + " " + p.getLastName()) .collect(Collectors.toList());
|
命名lambda:
// Implementation details Predicate<Person> isMaleOrAdult = p -> { if (p.isMale()) { return true; } LocalDate now = LocalDate.now(); return p.isAdult(now); }; Function<Person, String> concatenateFirstAndLastName = p -> p.getFirstName() + " " + p.getLastName();
// Core persons.streams() .filter(isMaleOrAdult) .map(concatenateFirstAndLastName)
|
流(最后一行)变得更具可读性,而不是隐藏在实现细节的后面。它不会阻止开发人员阅读它们,只有在必要时才阅读。