Lambdas in Java 8: The Shortest Guide You'll Ever Need

Lambdas in Java 8: The Shortest Guide You'll Ever Need

Lambdas offer a concise way to define anonymous methods in Java, i.e. methods not requiring to be part of a class definition and object instantiations.

You can assign these methods to variables and pass these variables around just like one might do in python or JS!

Here is how:

We all know how to define a method:

Integer (Integer x) {return x * 2;}

A lambda function however can be shortened as Java now has type inference for Lambda functions! All you need is an arrow! And this can be done inline.

MyJavaFunction function = (x) -> {
    return x * 2;
}

This can be shortened even more to this if it is a single line of code.

MyJavaFunction function = x -> x * 2;

But what is MyJavaFunction?

public class Main {
    public static void main(String[] args) {
// creating a lambda
        MyJavaFunction myJavaFunction =  x -> x * 2;
// running the method
        System.out.println(myJavaFunction.doStuff(4));
    }

// Java uses interfaces to make lambdas possible
 interface MyJavaFunction {
     Integer doStuff(Integer x);
 }
}

It's just a faster way to create "Functions" without needing an explicit class.

These lambda functions can be created only as Single Abstract Method (SAM) interfaces.

That is you can define one method inside an interface and create any kind of implementation as long as you stick to the structure of that abstract method.

public class Main {
    public static void main(String[] args) {
        //The below won't work since Multiply1Number isn't a SAM!
        //Multiply1Number lambdaFunction =  x -> x * 2;

        // This is a SAM. This will get instantiated :)
        Multiply2Numbers lambdaFunction = (x , y) -> x * y;
    }
    interface Multiply1Number {
        Integer doStuff(Integer x);
//adding a second method won't let you create lambdas as this isn't SAM
        Integer multiply(Integer x , Integer y);  
    }

/**be sure to add the below annotation in order to restrict 
the interface to just be a SAM interface. 
*/ 
    @FunctionalInterface
    interface Multiply2Numbers {
// create a seperate SAM if you need a different signature
        Integer multiply(Integer x, Integer y);
    }
}

Lambdas makes it incredibly easy to reuse an interface on the fly.

public class Main {
    public static void main(String[] args) {
        // you can create any type of computer
        Computer substraction = (x , y) -> x - y;

        Computer multiply = (x , y) -> x * y;

        Computer addition = (x , y) -> x + y;

        // You can implement your printer to take in any kind of computer
        Printer printer = (computer, x, y) -> System.out.println(computer.compute(x, y));

        // You can pass your lambda to other lambdas
        printer.print(addition, 1, 1);
        printer.print(substraction, 1, 1);
    }

    @FunctionalInterface
    interface Computer {
        Integer compute(Integer x, Integer y);
    }
    @FunctionalInterface
    interface Printer {
        void print(Computer computer, int x, int y);
    }
}

"Functional programming" as we call this approach is in many ways quite distinct from traditional Object Oriented Programming and we will be looking at this more in my next blog post!