Java 8 Lambdas - Syntactic Sugar for Interfaces

All About Assigning Function Definitions To Variables

While languages such as Python support using functions as a type, Java must work around this deficiency by reworking a construct it already has.  In this case, Java  uses interfaces, with a bit of syntactic sugar, to accomplish the same goal.

For example, in Python assigning a function definition to a variable is quite trivial:

my_function = def print_name(name): print(name)

#Or through lambda notation:

my_function = lambda name: print(name)

#Either way, you can then simply use the call below to print your name to the console:
my_function('Renan')
Functional Interfaces In Disguise

Since the example above is not quite possible in Java, it must rely on the closest available tool in its toolbox: the functional interface.

If you are not familiar with the terminology, it is certainly nothing to be afraid of.  A functional interface is simply an interface which contains one, and only one, method.

The fact that functional interfaces have only one method allows Java to directly map the lambda expression to the interface’s single method.

So before using lambdas in Java, you basically need to tell Java 2 things:

  1. The return type of your lambda expression, which is simply the interface type
  2. The parameter type(s) for your lambda’s parameter(s),  if any parameters are present

At its most basic level, the syntax for lambdas in Java is quite familiar:

(arg0,[arg1],[argN]) -> expression;

Our Python example above can be roughly translated into:

public class Main {

	//Declare type returned by lambda:
	interface NamePrinter{
		void printName(String name);
	}
	
	public static void main(String args[]){
		//Assign lambda to variable:
		NamePrinter namePrinter = (name) -> System.out.println(name);

		//Execute by using:
		namePrinter.printName("Renan");
	}
}

The equivalent pre-Java 8 code allows us to trully appreciate the new “short hand notation”.

public class Main {

	//Declare type returned by lambda:
	interface NamePrinter{
		void printName(String name);
	}
	
	public static void main(String args[]){
		//The one line lambda (name) -> System.out.println(name) is able to substitute all of this:
		NamePrinter namePrinter = new NamePrinter(){
			@Override
			public void printName(String name) {
				System.out.println(name);
			}
		};
		
		//Execute by using:
		namePrinter.printName("Renan");
	}
}
Less Verbosity One Version at a Time

In conclusion, as Java developers, lambdas provide our money makers (i.e. our fingers) with some much needed rest.  It allows Java developers to literally express ourselves with less words, which is truly great.  If Java would now just adopt the “var” keyword for type inference, as C# does, I would be one happy camper :)