Java 8 – Re using Lambda Expressions

Java 8 – Re using Lambda Expressions

In my previous Java 8 Lambda expression blog, I tried to explain what is a Lambda expression in general, how to create a Lambda expression in Java 8 etc. Here we are going to look at the re usability perspective of the Lambda expression. It is very much required to re use the code or apply the DRY design principle when we are programming.

Let’s take some example to start with, Here I am trying to create a List of countries for each region, and trying to find the number of countries start with letter say “B” or “N”. Perhaps, to achieve the same result in the conventional way of Java we should run a loop by Iterating the list and putting a if condition and lot of unnecessary code.

Here is how the traditional code looks like


public class OldWay {
     final static List<String> asia =
     Arrays.asList("India", "Nepal", "China", "Singapore", "Srilanka", "Bhutan", "Bangladesh");

     final static List<String> europe =
     Arrays.asList("Netherlands", "Denmark", "Sweden", "Norway", "Ireland", "Britain", "Spain");

public static void main(String[] args) {
     int count = 0;
     for(String ctry : asia){
     if(ctry.substring(0,1).equals("N")){ count ++; }
}
     System.out.println("Countries name starting with N :" + count);
     }
}

So, we have a much better way to achieve the same thing with lambda expressions. It is easy and simple. We need to tune our Java brains a bit to think in functional way. For me it took long time to tune myself ūüôā


package com.ravi.lambda.advanced;

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

public class ExampleCollections {

     public static void main(String[] args) {
          final List<String> asia =
          Arrays.asList("India", "Nepal", "China", "Singapore", "Srilanka", "Bhutan", "Bangladesh");

          final List<String> europe =
          Arrays.asList("Netherlands", "Denmark", "Sweden", "Norway", "Ireland", "Britain", "Spain");

         // re using the Lambda Expression ...
         final Predicate<String> startsWithB = name -> name.startsWith("B");

         final long countStartswithBinAsia = asia.stream().filter(startsWithB).count();

         System.out.println(" Asian Countries starts with B :" + countStartswithBinAsia);

         final long countStartswithBinEurope = europe.stream().filter(startsWithB).count();

         System.out.println(" European Countries starts with B :" + countStartswithBinEurope);

       }

}

Output:


Asian Countries starts with B :2
European Countries starts with B :1

Now in the above example we have seen a Predicate which is getting re used as a method in Java. But there is a problem here, as we are not able to reuse this predicate for any other character than B. Below we would look at the Predicate as a full fledged method and could be re usable in any other class with a parameter to it. This is the best way to re use a predicate.


package com.ravi.lambda.advanced;

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

public class ExampleCollections {

// re using the Lambda Expression ... with whatever character you want !!!
public static Predicate<String> startsWithCharacter(final String character) {
return name -> name.startsWith(character);
}

public static void main(String[] args) {
     final List<String> asia =
     Arrays.asList("India", "Nepal", "China", "Singapore", "Srilanka", "Bhutan", "Bangladesh");

     final List<String> europe =
     Arrays.asList("Netherlands", "Denmark", "Sweden", "Norway", "Ireland", "Britain", "Spain");

    final long countStartswithBinAsia = asia.stream().filter(startsWithCharacter("N")).count();

    System.out.println(" Asian Countries starts with N :" + countStartswithBinAsia);

     final long countStartswithBinEurope = europe.stream().filter(startsWithCharacter("N")).count();

     System.out.println(" European Countries starts with N :" + countStartswithBinEurope);

     }

}

Output:


Asian Countries starts with N :1
European Countries starts with N :2

Hope this was useful to you and in next article, I would like to discuss the FunctionalInterface in Java 8.
Thanks and Happy Reading…

Advertisements
Lambda Expression Basic Example – Java 8

Lambda Expression Basic Example – Java 8

Why Java 8 supports functional programming is a big debate we can avoid for now. Lets try to understand what the features Java 8 has given for supporting functional programming. First thing we hear is Java 8 has provided Lambda Expressions, According to Oracle’s Chief Architect Mark Reinhold, The Single Largest Upgrade Ever.¬†Lets start learning the Lambda expression now.

Lambda’s are anonymous functions which doesn’t need a name, input arguments or return type. If I say like that you might think why and how they are useful ?

Shall we really use them? If you could see a very small and basic example given for Prime Numbers, you would be able to understand the simplicity and ease of use of Lambda’s. Explanation of the code is given below the example.

Note: Please look at the methods [ isPrimeNum(Old School of Coding) and isPrime( New School of Functional Coding)].

package com.ravi.lambda;

import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.IntStream;

public class PrimeNumber {

     public static void main(String[] args) {

          // Old Style
          System.out.println(" 1 is Prime ? -" + isPrimeNum(1));
          System.out.println(" 2 is Prime ? -" + isPrimeNum(2));
          System.out.println(" 3 is Prime ? -" + isPrimeNum(3));
          System.out.println(" 4 is Prime ? -" + isPrimeNum(4));

          // New Style
          System.out.println(" 1 is Prime ? -" + isPrime(1));
          System.out.println(" 2 is Prime ? -" + isPrime(2));
          System.out.println(" 3 is Prime ? -" + isPrime(3));
          System.out.println(" 4 is Prime ? -" + isPrime(4));

     }
     /**
     *
     * @param number
     * @return
     */
     static boolean isPrimeNum(Integer number){
          if(number == 1 ){
              return false;
          }
          for(int i=2; i< number; i++){
               if(number % i == 0 ) {
                    return false;
               }
          }
     return true;
     }

     /**
     *
     * @param number
     * @return
     */
     static boolean isPrime(int number){
     // Functional or Declarative Way of doing
     return number > 1 && IntStream.range(2, number).noneMatch( index -> number % index == 0 );
     }
}

Lets look at the isPrimeNum method. Did you notice anything strange ? I guess no, because we know that Java works that way.

Loop over all numbers which are greater than 2 till n-1, as 1 is not a prime number and any number can be divisible by 1, we would like to start with 2. So, we had to handle the case of 1 separately.

Instead of Looping the code we could do it with Functional way Р isPrime demonstrates that code.

The easiest way to identify a Lambda Expression is “->“. A Lambda can take Optional Parameters, and executes the expressions or statements with in the braces. ¬†Let me explain the above example.

First condition we are checking is number greater than 1 and Stream is the new API given by Java 8 [Which can be used in place of Collections… Read More ] which provides sequence of events. I have used “IntStream” which is defined for Integers, which has this Static Method called Range¬†(Runs the loop from 2 till the given number )and noneMatch (returns a Boolean value,¬†whether no elements of this stream match the provided predicate )instance method which take Predicate as input, this is where we have used a Lambda expression to see the number is divisible by the index.

Lambda’s has too many things, I hope this is a very good starting point for you. I would try to give you how to make it generic and re use a Lambda expression in next blog.

References:

Oracle Blog about Lambda Expressions

Lambda Expression FAQ