0

I'm reading about lambda's on https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

In Approach 1 they mention

"You would have to rewrite a lot of your API to accommodate this change. In addition, this approach is unnecessarily restrictive; what if you wanted to print members younger than a certain age, for example"

public static void printPersonsOlderThan(List<Person> roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}

In Approach 5 they use lambda expression:

printPersons(
    roster,
    (Person p) -> p.getGender() == Person.Sex.MALE
        && p.getAge() >= 18
        && p.getAge() <= 25
);

However, even in this lambda expression, we have to modify the API when we want to modify the search criteria.

Why is using a lambda here better compared to using a custom method in the first approach?

4
  • 6
    If your question is regarding code, the code in question needs to be posted here directly, as text. Commented Oct 27, 2017 at 1:01
  • "Even in this lambda expression, we've to modify the API when we've to modify the search criteria." What? Why? If I want to use a different criterion, I use a different lambda expression. The function remains the same. Commented Oct 27, 2017 at 1:03
  • I don't see how Approach 5 requires modifying the API. Commented Oct 27, 2017 at 1:03
  • This has nothing to do with lambda... Approach 5 has a functional interface parameter, which contains the checks to test a condition. You could specify this without a lambda, just implementing the interface, and passing an instance of the implementing class. A lambda is just an "eye candy" to the programmer, to make code more readable, more simple... Commented Oct 27, 2017 at 1:36

1 Answer 1

2

The problem with small examples is that they sometimes hide the real benefits. In this case they are looking at a method that contains reporting logic. Approach 1 looks like this:

public static void printPersonsOlderThan(List<Person> roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}

The problem is, if you need other reporting, such as

  • persons younger than a certain age
  • persons between specific ages
  • persons of a specific gender
  • etc

You will have to write a new method for each use case, where you re-implement the for-loop and printing instructions:

for (Person p : roster) {
    if ( specificCondition) {
        p.printPerson();
    }
}

What you really want is to re-use all the logic around that condition and only re-write the specific search condition for your use case, without re-writing looping logic and print logic.

In approach 5, the printPersons method takes a lambda as parameter.

printPersons(
    roster,
    (Person p) -> p.getGender() == Person.Sex.MALE
        && p.getAge() >= 18
        && p.getAge() <= 25
);

You can pass whatever search query to the printPersons method, without having to write new methods like printMalePersonsOlderThanAndYoungerThan where you have to re-write the full for-loop and all the printing instructions.

At the specific moment the printPersons is written, the Person getGender() method might even not yet exist, so it would have been impossible to deliver a printMalePersonsOlderThanAndYoungerThan a priori. So another advantage of approach 5 is that you can provide methods that are future proof and if your model changes, you will not have to write any more additional code than the specific condition.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.