Java has additional functionalities since Java 8.

You can now pass functions around as if it were data. Or just a recipe.

Study the oracle tutorial on Lambda and Streams:

1. Slides:

There is also a summary on lambda under lambdaandfunctions.html

2. Exercises

2.1. Comparator as lambda.

If you study the Java doc for the Comparator interface, you will see there is only one abstract method.[1] This makes this interface a candidate for a functional interface, and indeed it is.

A functional interface is an interface that has only one abstract method in it. Some of them you already know. For example, the interfaces Runnable or ActionListener are functional interfaces.

In this exercise, you will write a series of Comparators, each handling a different comparable aspect.

Use the following class as the element you test with.

Cabbage class (visibility modifiers left out for brevity).
enum Odour{
  NONE(0),THRESHOLD(1), WEAK(2),DISTINCT(3),STRONG(4),VERY_STRONG(5),INTOLERABLE(6);
}

class Cabbage {
  String name;
  int weight; // in grams
  double volume; // in litres
  Odour stinkyNess; // odour in
  ... // constructor and fields left out as an exercise.

  String getName()...

  double getWeight()...

}

Use the following template to create your comparators, written as lambda expressions:

comparator template
Comparator<Cabbage> weightComparator = (c1,c2) -> ....

Test and implement comparators for name, weight, volume and stinkyNess.

Use the following test data:

cabbages
Cabbage sprout = new Cabbage("Brussel Sprouts", 10, 0.2,  STRONG);
Cabbage cauliflower = new Cabbage("Cauliflower", 1000, 1.5,  DISTINCT);
Cabbage kale = new Cabbage("Kale", 500, 0.700,  WEAK);
Cabbage white = new Cabbage("White Cabbage", 1200,1.2, DISTINCT);
Cabbage cabbage = new Cabbage("Cabbage", 600,0.480, STRONG);
Cabbage savoy = new Cabbage("Savoy Cabbage", 800, 1.8, VERY_STRONG);

2.2. Lambda based calculator

ExtraChallenge Challenging exercise:

Create a simple console based calculator.

You can use a scanner to take the input.

Use an enum to define the operations and use a functional interface, in particular java.util.function.IntBinaryOperator to do the calculations.

The netbeans project to start with will be injected into your repository. This is a fill in the blanks exercise.

In this exercise you will use a parameterised test, as described in [Kaczanowski, ch 3], the variant that is built in in JUnit 4. The test data is given in the project.

2.2.1. TDD: write your tests.

You have to do two things in the given test class:

  1. Create the Constructor for the test class, which takes 5 parameters, which are all saved as fields in the test class.
    The test framework will invoke this constructor for each test with one of the lines that is produced by the testData()` method. The parameters are

    1. String message, shown when the test fails.

    2. String representing the operation, like "+" for the add operation.

    3. int expected value.

    4. int a first input and

    5. int b second input to the operation.

  2. Write the one and only test method, which uses the fields you initialised in the constructor.
    This test should assert that the result of the computation matches the expected value, by using the enum class' Operation get(String symbol) method to lookup the Operation object.
    As usual, the JUnit will output the message if and only if the test fails.

2.2.2. Implement the Operator enum.

  1. Start with the Constructor, which takes two parameters

    1. String symbol, like * for times

    2. IntBinaryOperator operator as a lambda expression, specifying the actual computation.

  2. implement get(..) or getOp(…​) (you decide which has your preference, adapt the test to match your choice), which translates symbol to the actual enum value.

    1. get(…​) simply loops through the values[] of the enum to see if its symbol maps. If it does, return the enum value, if not found return null;

    2. getOp(…​) uses a static map. This static map is initialised by a static {…​} block, which is the way Java allows you to do work when your class is loaded.

  3. implement compute(…​) by letting the stored lambda expression do its work.

2.2.3. Play with it.

Enable the commented code in the main class, and lo and behold: You made it working.




1. equals(Object other) does not count, it is already defined in Object