The functional paradigm in Java – What are lambda expressions?

Functional languages are becoming more popular and popular day after day, languages like Scala and Erlang are a little example of it.

You may think, Why all this popularity?

Functional paradigm and languages work in this way:

  • You do not have variables, but immutable symbols with one unique value, from the beginning to the end
  • No loops, just ricursion
  • Higher level functions, in the sense that you can pass a function to another function as a formal parameter
  • No collateral effects, since variables are constants
  • Good parallelism
  • You have to focus on the “What are you doing” instead of “How you are doing” when writing code

These are just some characteristics of this paradigm, you can find much more on Google, this was just a little introduction.

 

Functional paradigm and Java

Yes, we are not seeing a new pure/impure functional language, but we’ll learn how to use part of this paradigm in Java.

In particular, this lesson I am going to explain you why this paradigm is present in Java and how use it, thanks to the so called lambda expressions or shortly, lambdas.

Wasn’t Java an OOP (Object Oriented Paradigm) language?

Yes, it was till version 8. Then something changed.

The problem was mainly caused by a simple operation that in Java wasn’t so easy and light (sintaxically) to achieve. I am talking about passing a method to a function.

If you want (before) to do that, you had to create an anonymous inner class, on the fly, and pass it to the method, for instance something like:

method1( param1, param2, new className() {

void doSomething(Type param1){ … } });

Imagine if doSomething(param1) were big, the syntax would be a lot more dirty.

But the most important thing is that you needed to instantiate a whole object just to use a single function, in some situation it would be a waste of memory!

Lambda Expressions

Starting from Java 8 we have the Lambda Expressions, whose name comes from the Lambda Calculus , intended to add some functional capabilities to an OOP oriented language as Java, therefore making some operations, like passing a method to another one,  easier tasks.

Functional interfaces

If you want to use the lambdas, you have to firstly know the basis.

A functional interface is a standard Java interface that has a single abstract method.

Example:

interface Drawable {

draw(Graphic g);

}

This kind of interface will be used to pass the lambda expression to the caller and it is required since lambdas have types inference. In the sense that they automatically deduct the variable type, hence, to do that, the interface must have a single method.

How to create Endless Streams of Data in Java

Differences between usages:

  • OOP

           new method( param1, new Drawable () { draw(Graphic p) { … } });

  • Lambdas

          new method( param1, (p) -> { .. } );  // Where p is a Graphic object

You can clearly notice how the syntax has got much concise, but this is only one of the avantages.

Java offers some default Functional interfaces, most important are:

  • Predicate<T>: contains the abstract method boolean test(T t) used for filtering or testing a condition
  • Consumer<T>: contains void accept(T t) used to pass a simple void method to do something with the argument, for example print it
  • Function<T,U>: contains U apply(T t) good to elaborate data and output something of type U

Complete example: You have a list of people and you want to print only the females.

class Person() {

private char gender;

Person( .., .. ) { } // Constructor

public char getGender() return gender;

public void filteringList(List<Person> people, Predicate<Persona> filter ) {

for ( Person p : people ) {

if ( filter.test(p) ) System.out.println(p); // If test is satisfied, print the person

}

}

}

Usage:

We have the List ‘people’ made of: Marie, Lucy, Bob, Meave

filteringList( people, ( person ) -> person.getGender() == ‘F’ );

Output:

Marie

Lucy

Meave

And if you want to print only Males? Easy.

filteringList( people, ( person ) -> person.getGender() == ‘M’ );

 

Some limitations of lambdas, obviously they are logical according to the functional paradigm:

  • Cannot access non-final variables from outside scope
  • Can’t modify outer scope

CONCLUSION

As you can see, with a single method you can test infinite conditions, you just have to call the same method with a different test.

In this lesson we have seen the basis, in the next ones we’ll see some more advanced examples about: method references, ordering, the technique of map-reducing and finally parallelism.

Welcome to the world of functional paradigm!

Leave a Reply

Your email address will not be published.