11.3. Motivating Example¶
This section will focus on why we need this special syntax by comparing the lambda expression syntax to the process of creating a separate, named class (we will call this the class-based approach) we followed in the Interfaces Chapter.
Since our focus is on functional interfaces, we cannot use the
PaymentProcessor Example
from chapter 5 to compare lambda expression syntax to the
named class syntax. Instead, we will use the functional interface,
DiscountStrategy
, introduced in the previous section and
repeated below:
public interface DiscountStrategy {
/**
* Applies this discount strategy to the specified
* {@code originalPrice} and returns the adjusted
* price.
*
* @param originalPrice the original price of the item.
* @return the discounted price.
*/
double apply(double originalPrice);
} // apply
11.3.1. Implementing the Functional Interface¶
Test Yourself
Take a few minutes to review the process of Implementing an
Interface and then
create an implementing class called SeniorCitizenDiscount
that
has an apply
method that reduces the original price by 10%.
Test Yourself Solution (Don’t open until completing the question above)
Your class should look something like this:
public class SeniorCitizenDiscount implements DiscountStrategy {
@Override
public double apply(double originalPrice) {
return originalPrice * 0.9;
} // apply
} // SeniorCitizenDiscount
Once we’ve created the SeniorCitizenDiscount
class, we would also
have to create an object of type SeniorCitizenDiscount
in our
application and then it to apply the discount. Of course, we would
also have to modify our compilation script and check our dependencies
to ensure the file would compile appropriately.
Below, we have two versions of a full program that implements
the DiscountStrategy
interface with two different types
of discounts (senior citizen discount and student discount) and
applies those discounts to a given price. Both programs produce
identical output.
Note
As you read through the code below, we want you to pay attention to the notes above the code outlining the pros/cons of each approach and the length of the two programs. You should notice that the lambda version of the program is much shorter and confined to a single file, but uses syntax that you are currently unfamiliar with (more details to come).
The class-based approach that we learned about in the
Interfaces Chapter
can certainly be used to implement our interface.
However, using this approach requires a separate .java
file for each implementation. Since the interface
has only one abstract method, there is a lot of overhead
to create these two classes. We have to make the .java
files, update our compilation script, copy (or retype)
the class declaration and full signature of the method,
etc. Lambda expressions help us avoid all of this.
1public class SeniorCitizenDiscount implements DiscountStrategy {
2
3 @Override
4 public double apply(double price) {
5 return price * 0.9;
6 } // apply
7
8} // SeniorCitizenDiscount
1public class StudentDiscount implements DiscountStrategy {
2
3 @Override
4 public double apply(double price) {
5 if (price > 2.00) {
6 return price - 2.00;
7 } // if
8 return price;
9 } // apply
10
11} // StudentDiscount
1public class Driver {
2
3 public static void main(String[] args) {
4 double price = 10.95;
5
6 DiscountStrategy senior = new SeniorCitizenDiscount();
7 DiscountStrategy student = new StudentDiscount();
8
9 double seniorPrice = senior.apply(price);
10 double studentPrice = student.apply(price);
11
12 System.out.printf("The senior price is %f\n", seniorPrice);
13 System.out.printf("The student price is %f\n", studentPrice);
14 } // main
15
16} // Driver
The lambda expressions defined in Driver2
fully implement
the functional interface in the same way as the class-based
approach without the need for separate classes. Here, we
are providing the implementation for the single abstract
method apply
directly.
1public class Driver2 {
2
3 public static void main(String[] args) {
4 double originalPrice = 10.95;
5
6 DiscountStrategy senior = (price) -> {
7 return price * 0.9;
8 };
9
10 DiscountStrategy student = (price) -> {
11 if (price > 2.00) {
12 return price - 2.00;
13 } // if
14 return price;
15 };
16
17 double seniorPrice = senior.apply(originalPrice);
18 double studentPrice = student.apply(originalPrice);
19
20 System.out.printf("The senior price is %f\n", seniorPrice);
21 System.out.printf("The student price is %f\n", studentPrice);
22 } // main
23
24} // Driver
In the following sections, we will further explain the lambda expression syntax and demonstrate how they can be used to implement other functional interfaces.